从C ++ 11草案,7.5(第1段):
两种不同语言的功能类型 链接是不同的类型,即使它们是相同的。
所以我可以根据语言链接做过载:
extern "C" typedef void (*c_function)();
typedef void (*cpp_function)();
void call_fun(c_function f)
{
}
void call_fun(cpp_function f)
{
}
extern "C" void my_c()
{
}
void my_cpp()
{
}
int main()
{
call_fun(my_c);
call_fun(my_cpp);
}
但是,使用GCC 4.7.1,此示例代码会显示错误消息:
test.cpp: In function 'void call_fun(cpp_function)':
test.cpp:7:6: error: redefinition of 'void call_fun(cpp_function)'
test.cpp:4:6: error: 'void call_fun(c_function)' previously defined here
使用CLang ++:
test.cpp:7:6: error: redefinition of 'call_fun'
void call_fun(cpp_function f)
^
test.cpp:4:6: note: previous definition is here
void call_fun(c_function f)
^
现在问题:
我对标准的理解是否正确?这段代码有效吗?
是否有人知道这些是编译器中的错误还是为了兼容性而故意这样做?
答案 0 :(得分:10)
代码显然有效。 G ++(和许多其他编译器)是一个 关于将链接集成到类型中的位置松散(温和地说)。
答案 1 :(得分:8)
这是gcc中的一个已知错误,并且它们记录了它不符合,因为这个错误阻止了超级错误,“C ++ 98一致性问题”。
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
检查创建日期。
关于引入修复的实用性,最后会有一些讨论。所以你的上一个问题的答案是“两个”:这是一个错误和这个错误故意留给了兼容性。
具有相同问题的其他编译器可能独立地产生了错误,但我认为他们更有可能知道这是错误的但是想要与gcc进行错误兼容。
答案 2 :(得分:1)
对于它的价值,此代码也无法使用VS2012中的默认设置进行编译:
(8) error C2084: function 'void call_fun(c_function)' already has a body
(4) see previous definition of 'call_fun'
(19) error C3861: 'call_fun': identifier not found
(20) error C3861: 'call_fun': identifier not found