С нормальными функциями можно написать
extern "C" int Frotz(int); // in a header
int Frotz(int x) { return x; }
С указателями функций, однако, это, похоже, было непоследовательно реализовано между компиляторами.
extern "C" int Klutz(int (*)(int), int);
int Klutz(int (*fptr)(int), int x) { return (*fptr)(x); }
В объявлении аргумент также extern "C"
. В определении большинство компиляторов, похоже, соответствуют этим функциям и выполняют функцию Klutz
a extern "C"
. Однако составители Sun и Cray интерпретируют эти функции как разные, создавая перегруженный int Klutz(int (*fptr)(int), int x)
, который позже генерирует ошибку времени привязки.
Несмотря на то, что раздел 7.5.5 на С++ 98 и С++ 11 гарантирует интерпретацию Frotz
, я не могу сказать, является ли стандарт двусмысленным в отношении того, должно ли соответствие extern "C"
происходить до или после проверки перегрузки.
Если Klutz
выше генерирует искаженный (С++) символ или символ extern "C"
?
EDIT 1
Я мог бы использовать typedef, чтобы устранить смещение указателя функции на C или С++ ABI, но меня интересует, содержит ли здесь код (a) Klutz
для связи С++, (b) определяет его, чтобы иметь C link или (c) является неоднозначным в соответствии со стандартом, поэтому компиляторы могут свободно выбирать, как интерпретировать его.
EDIT 2
Это, по-видимому, известная проблема, по крайней мере, теми компиляторами, в которых есть поисковые трекеры. В моих тестах GCC, Clang, Intel, MSVC, IBM XL, PathScale, PGI и Open64 не различают типы функций, которые идентичны, кроме языковой привязки, как это явно требуется стандартом (см. Раздел 7.5.1, приведенный в принятый ответ). Исправление этого может сломать много существующего кода и потребовать изменения ABI. Я не знаю какого-либо компилятора, который на самом деле использует другое соглашение о вызове для связи языка C и С++.
-
Ошибка GCC: "Поиск причин, чтобы попросить удалить эту функцию из следующего стандарта, относится к релевантным;-)"... "И мы даже можем принять решение о официальном WONTFIX".
-
Ошибка Clang: "Я напугана тем, что на самом деле применяю это правило, потому что это правильно означает создание языковой связки части канонический тип, который сломает тонну кода".