Ошибка компилятора для конфликтующих объявлений переменных: "конфликтует с новым объявлением со связью" 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)
Мой вопрос: почему это ошибка, если нет функциональной разницы?
Кроме того, я не против изменения кода; Я хотел знать, происходит ли что-то большее, чем просто "стандарт говорит, что это плохо сформировано".
1 ответ
Я просмотрел различные * стековые сайты и в основном нашел вопросы по этой теме, касающиеся функций с конфликтующими спецификациями связи.
Я нашел свой [первый] ответ в базе данных gcc bugzilla:
Стандарт гласит в п. 7.5/5: "Если два объявления одной и той же функции или объекта задают разные спецификации связей [...], программа плохо сформирована, если объявления появляются в одной и той же единице перевода [...]". Вот почему такой код в комментарии 6 теперь отклонен.
Независимо от того, верно ли мое предположение (о функциональной разнице между связями C/C++ для переменных POD) или нет, похоже, ошибка предназначена для предотвращения плохого стиля.
Затем я нашел эту статью о спецификаторах классов хранения и одну о языковой связи. Я не видел в этих статьях ничего, что противоречило бы тому, что я узнал до сих пор; 2-й говорит:
Аналогично, две переменные в одном и том же пространстве имен не могут иметь двух разных языковых связей.