我刚才注意到C++标准说C和C++函数有不同的和不兼容的类型,即使它们的类型签名是相同的(更多信息请参阅这个问题).这意味着您在技术上不允许将C++函数传递给C函数pthread_create().
我很好奇是否有任何平台在使用两个ABI实际上是不同的(除了显而易见的名称差异).具体来说,有没有人知道这个C++程序无法编译和运行的任何平台?
#include <assert.h>
extern "C" int run(int (*f)(int), int x) { return f(x); }
int times2(int x) { return x * 2; }
int main(int argc, char *argv[]) {
int a = times2(argc);
// This is undefined behavior according to C++ because I am passing an
// "extern C++" function pointer to an "extern C" function.
int b = run(×2, argc);
assert(a == b);
return a;
}
Run Code Online (Sandbox Code Playgroud)
我不知道ABI不同的任何平台,但即使C和C++调用约定相同,C++标准也要求编译器为程序发出诊断.指向函数的指针与C语言的链接是与指向函数的指针 - 与C++ - 语言链接不同的类型,因此您应该能够run()像这样重载:
extern "C" int run(int (*f)(int), int x) { return f(x); }
extern "C++" int run(int (*f)(int), int x) { return f(x); }
Run Code Online (Sandbox Code Playgroud)
现在当你调用run(times)它应该调用第二个,所以它遵循第一个不可调用(没有从指针到函数与C语言链接转换为指向函数的指针 - C++ - 语言链接)等原始代码应该导致编译器诊断.但是,大多数编译器都会出错,例如http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
注意:Solaris编译器会诊断不兼容的语言链接,作为警告:
"t.c", line 11: Warning (Anachronism): Formal argument f of type extern "C" int(*)(int) in call to run(extern "C" int(*)(int), int) is being passed int(*)(int).
如果你重载run与extern "C++"函数它正确调用extern "C++"之一run(times).
| 归档时间: |
|
| 查看次数: |
546 次 |
| 最近记录: |