Возможная неоднозначность с внешними «C», перегрузкой и указателями на функции
С нормальными функциями можно написать
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
extern "C"
функция. Компиляторы Sun и Cray, однако, интерпретируют эти функции как разные, создавая перегруженныеint Klutz(int (*fptr)(int), int x)
, который позже генерирует ошибку времени соединения.
Хотя Раздел 7.5.5 C ++ 98 и C ++ 11 гарантирует интерпретациюFrotz
Я не могу сказать, является ли стандарт двусмысленнымextern "C"
сопоставление должно происходить до или после проверки на перегрузку.
ДолженKlutz
выше генерировать искаженный (C ++) символ илиextern "C"
условное обозначение?
Я мог бы использовать typedef для устранения неоднозначности указателя на функцию, чтобы иметь C или C ++ ABI, но яменя интересует, определяет ли код здесь (а)Klutz
чтобы иметь связь C ++, (b) определяет, что она имеет связь C, или (c) является неоднозначной в соответствии со стандартом, так что компиляторы могут сами выбирать, как ее интерпретировать.
Похоже, это известная проблема, по крайней мере, для тех компиляторов, у которых есть трекеры с возможностью поиска. В моих тестах GCC, Clang, Intel, MSVC, IBM XL, PathScale, PGI и Open64 все не смогли различить типы функций, которые идентичны, кроме языковой связи, как это явно требуется стандартом (см. Раздел 7.5.1, процитированный в принятый ответ). Исправление этого сломало бы много существующего кода и потребовало бы изменения ABI. Я'Я не знаю ни одного компилятора, который фактически использует другое соглашение о вызовах для языковой связи C и C ++.
Ошибка GCC: "Поиск причин для удаления этой функции из следующего стандарта является уместным ;-) " ... "И мы можем даже принять решение об официальном WONTFIX. "
Ошибка лягушки: «Я»Я в ужасе от фактического применения этого правила, потому что его правильное выполнение означает превращение языковой связи в канонический тип, что может нарушить тонну кода ».