Ошибка компилятора из-за конфликтующих объявлений переменных: конфликтует с новым объявлением с привязкой 'C'

Я наткнулся на устаревший код, который не может быть построен на более новом компиляторе. Свернутый пример:

int x;
extern "C" { int x }; // conflicts with C++ linkage above
// note: without the braces it would've been equivalent to:
// extern "C" { extern int x; }
//
// for reference, see the notes section here:
//   http://en.cppreference.com/w/cpp/language/language_linkage#notes

Старые компиляторы не помечали это, но и gcc (начиная с 4.1.2), и clang помечают это.

Вывод Clang:

error: declaration of 'x' has different language linkage

Вывод GCC:

error: previous declaration of 'int x' with 'C++' linkage
error: conflicts with new declaration with 'C' linkage

Это меня удивило, потому что компилятор не искажает x каким-либо особым образом, и, насколько я могу судить, в объектном файле нет ничего другого, кроме отладочной информации (на основе моего, по общему признанию, неглубокого теста с objdump/readelf)

Мой вопрос: почему это ошибка, если функциональной разницы нет?

Кстати, я не против изменить код; Я хотел знать, происходит ли что-то большее, чем просто «стандарт говорит, что это неправильно».


person Brian Vandenberg    schedule 10.07.2015    source источник
comment
Могу я спросить, почему минус?   -  person Brian Vandenberg    schedule 11.07.2015


Ответы (1)


Я просмотрел различные сайты *stack и в основном нашел вопросы по этой теме, касающиеся функций с конфликтующими спецификациями компоновки.

Я нашел свой [первый] ответ в базе данных gcc bugzilla:

В стандарте 7.5/5 говорится: «Если два объявления одной и той же функции или объекта указывают разные спецификации компоновки [...], программа имеет неправильный формат, если объявления появляются в одной и той же единице перевода [...]». Вот почему такой код в комментарии 6 теперь отклоняется.

Верно ли мое предположение (о функциональной разнице между связью C/C++ для переменных POD) или нет, похоже, что ошибка предназначена для предотвращения плохого стиля.

Затем я нашел эту статью о спецификаторах класса хранения и одну о привязка к языку. Я не видел в этих статьях ничего противоречащего тому, что я узнал до сих пор; 2-й говорит:

Точно так же две переменные в одном и том же пространстве имен не могут иметь двух разных языковых связей.

person Brian Vandenberg    schedule 10.07.2015