【问题标题】:Checking if a function has C-linkage at compile-time [unsolvable]在编译时检查函数是否具有 C 链接 [无法解决]
【发布时间】:2010-05-29 19:40:17
【问题描述】:

有没有办法在编译时检查给定函数是否使用 C 链接(即使用 extern "C")声明?

我正在开发一个插件系统。每个插件都可以为插件加载代码提供工厂函数。但是,这必须通过名称(以及随后使用GetProcAddressdlsym)来完成。这要求使用 C 链接声明函数,以防止名称修改。如果引用的函数是使用 C++ 链接声明的(而不是在运行时发现具有该名称的函数不存在时),那么能够引发编译器错误会很好。

这是我的意思的简化示例:

extern "C" void my_func()
{
}

void my_other_func()
{
}

// Replace this struct with one that actually works
template<typename T>
struct is_c_linkage
{
    static const bool value = true;
};

template<typename T>
void assertCLinkage(T *func)
{
    static_assert(is_c_linkage<T>::value, "Supplied function does not have C-linkage");
}

int main()
{
    assertCLinkage(my_func); // Should compile
    assertCLinkage(my_other_func); // Should NOT compile
}

is_c_linkage 的可能实现是否会为第二个函数引发编译器错误,而不是第一个函数?我不确定这是否可能(尽管它可能作为编译器扩展存在,我仍然想知道)。谢谢。

【问题讨论】:

  • 我强烈怀疑这无法做到——尤其是不能以标准方式进行。不过,这个问题很有趣。
  • 我不太确定。但是即使可以做到,GCC 也很可能不支持它,因为它不知道 extern "C" 和 extern "C++" 函数类型的区别。因此它将两种类型视为相同。
  • 如果你要实现特定的知识,你最好让它适用于该实现而不是抛出错误
  • 好的,我假设这是不可能的(除了可能存在一些我不希望任何人知道的深奥的编译器特定的黑客攻击之外)。谢谢大家的信息和帮助。在没有“答案”的情况下,我应该做些什么来将问题标记为已关闭?
  • 您可以将“[unsolvable]”附加到问题标题中。

标签: c++ templates metaprogramming


【解决方案1】:

我同意 Jonathan Leffler 的观点,即以标准方式这可能是不可能的。也许这在某种程度上是可能的,这取决于编译器甚至编译器的版本,但是您必须尝试确定可能的方法并接受编译器的行为可能是无意的并且可能在以后的版本中“修复”的事实。

例如,对于 Debian Squeeze 上的 g++ 版本 4.4.4,您可能会使用这种方法为不是 stdcall 的函数引发编译器错误:

void my_func() __attribute__((stdcall));
void my_func() { }

void my_other_func() { }

template <typename ret_, typename... args_>
struct stdcall_fun_t
{
    typedef ret_ (*type)(args_...) __attribute__((stdcall));
};

int main()
{
    stdcall_fun_t<void>::type pFn(&my_func),
        pFn2(&my_other_func);
}

g++ -std=c++0x 无法编译此代码,因为:

SO2936360.cpp:17:错误:从“void ()()”到“void ()()”的无效转换

第 17 行是 pFn2 的声明。如果我去掉这个声明,那么编译成功。

很遗憾,这种技术不适用于cdecl

【讨论】:

    【解决方案2】:

    对于 Unix/Linux,如何使用“nm”分析生成的二进制文件并查找符号名称?我想这不是你的意思,但它仍然是编译时间。

    【讨论】:

      猜你喜欢
      • 2013-10-12
      • 2012-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-17
      • 1970-01-01
      • 2013-09-19
      • 2013-09-29
      相关资源
      最近更新 更多