Из проекта 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)
^
Теперь вопросы:
Правильно ли мое понимание стандарта? Этот код действителен?
Кто-нибудь знает, являются ли это ошибками в компиляторах или они намеренно делают это таким образом в целях совместимости?
Это известная ошибка в gcc, и они отмечают, что она не соответствует требованиям, поскольку эта ошибка блокирует проблему uber-bug, «проблемы соответствия C ++ 98».
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
Проверьте дату создания.
В конце есть дискуссия о практичности внесения исправления. Таким образом, ответ на ваш последний вопрос «оба»: это ошибка а также ошибка намеренно оставлена для совместимости.
Другие компиляторы с такой же ошибкой могли допустить ошибку независимо, но я думаю, что они также знают, что это неправильно, но хотят быть совместимыми с ошибками с gcc.
Код явно действителен. G ++ (и ряд других компиляторов) являются
немного мягко (мягко говоря) об интеграции связи в тип.
Для чего это стоит, этот код также не удается скомпилировать с настройками по умолчанию в 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