Проблема с ключевым словом экстерна в C++

Каково различие между следующими двумя объявлениями? Я думал, что они были эквивалентными, но первые демонстрационные работы и вторыми, не делает. Я подразумеваю, что это компилирует и работает, но выставочный пробел кода дисплея с поэлементным отображением. Я еще не ступил через него, но я пропускаю что-то очевидное? GUI_BITMAP является простой структурой, описывающей битовый массив. Это для VC ++ 2005, но я думаю, что он перестал работать в VC ++ 2008 также. Царапание моей головы на этом...

Демонстрационный 1:

extern "C" const GUI_BITMAP bmkeyA_cap_active;
extern "C" const GUI_BITMAP bmkeyA_cap_inactive;

Демонстрационные 2:

extern "C" 
{
   const GUI_BITMAP bmkeyA_cap_active;
   const GUI_BITMAP bmkeyA_cap_inactive;
};

Править: Больше исследования показало, что второй пример создает структуры, в то время как первое относится к внешним структурам. Второй пример не должен связываться, так как существует две переменные в глобальной области видимости с тем же именем. Но это не делает, это отправляет, нуль заполнил структуру к коду дисплея, который сдается. Хм.....

Редактирование 2: Выполнению того же кода через другой компилятор (IAR) на самом деле не удалось скомпилировать на Демонстрационных 2 с ошибкой о пропавших без вести конструктора по умолчанию. Таким образом, я предполагаю, что существует что-то тонкое о ключевом слове "экстерна", структурах и C++, который я не получаю. Если бы вещами в области экстерна были функции, то эти два образца были бы идентичным правом?

5
задан Jeff 30 March 2010 в 14:45
поделиться

2 ответа

Возможно, ваш компоновщик автоматически разрешает повторяющиеся символы за вашей спиной. Вы можете получить статические библиотеки от поставщика и связать их со своей программой - каково решение ситуации, когда у вас есть две такие библиотеки, и обе они определяют общий символ? Компоновщик просто разрешит это, выбрав то или иное определение, и предоставит вам разобраться с последствиями. Как вы справляетесь со стадией ссылки вашего приложения? У вас могут быть лучшие результаты, если вы напрямую связываете файлы .o вместо того, чтобы помещать их в промежуточные библиотеки перед компоновкой окончательного приложения.

Эта страница документации ARM хорошо описывает проблему - я ожидаю, что подобное поведение происходит и в вашем случае:

Множественные определения символа в разных объектах библиотеки не обязательно обнаруживаются. Как только компоновщик нашел подходящее определение для символа, он перестает искать другие. Если предположить, что объект, содержащий повторяющийся символ, не загружен по другим причинам, ошибки не произойдет. Это сделано намеренно и особенно полезно в некоторых ситуациях.

Изменить: при дополнительном поиске выяснилось, что эта проблема вызвана нарушением « Правила одного определения », и в результате компилятор / компоновщик не обязан сообщать вам о проблема. Это делает ваш вопрос дубликатом этого .

3
ответ дан 15 December 2019 в 06:22
поделиться

Второй пример может быть эквивалентен первому с дополнительным extern перед константой. В первом случае компилятор, вероятно, объединяет два использования extern. Во втором случае я бы предположил, что компилятор по какой-либо причине не учитывает все в области extern extern.

0
ответ дан 15 December 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: