18

来自 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)
     ^

现在的问题:

  • 我对标准的理解正确吗?此代码有效吗?

  • 有人知道这些是编译器中的错误,还是出于兼容性目的而故意这样做?

4

3 回答 3

10

该代码显然是有效的。G++(和许多其他编译器)在将链接集成到类型方面有点松懈(委婉地说)。

于 2012-09-18T09:58:15.760 回答
8

这是 gcc 中的一个已知错误,他们记录它不符合标准,因为这个错误阻止了超级错误,“C++98 一致性问题”。

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316

检查创建日期。

最后有一些关于引入修复的实用性的讨论。所以你最后一个问题的答案是“两者”:这是一个错误,并且为了兼容性而故意留下了这个错误。

其他具有相同问题的编译器可能独立地犯了错误,但我认为他们更有可能也知道这是错误的,但希望与 gcc 兼容。

于 2012-09-18T10:09:52.093 回答
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
于 2012-09-18T12:14:09.773 回答