2010-11-18 2 views
4

Iam смотрит на кусок кода, который создает глобальные переменные класса. Конструкторы этих классов вызывают таблицу символов одноплодные и добавляют эти указатели в нем ..C++ Глобальные переменные класса не создаются

В Keywords.cpp файл

class A : class KeyWord 
{ 
    A() { add(); } 
} A def; 

аналогична для ключевых слов B, C и т.д.

void KeyWord::add() 
{ 
CSymbolCtrl& c = CSymbolCtrl::GetInstance(); 
c.addToTable(this); 
} 

Эти единицы перевода скомпилированы для формирования библиотеки. Когда я «dumpbin» библиотеки, я вижу динамические инициализаторы для ADef, BDef и т. Д.

Нет в exe, когда я вызываю экземпляр CSymbolCtrl, я не нашел ADef, BDef .. сохраненный на его карте. Когда я устанавливаю точку останова в add(), она не попадает. Есть ли способ, по которому компоновщик игнорирует ADef, BDef, потому что на них нет ссылки?

+1

Не могли бы вы использовать достоверно компилируемый образец кода? –

ответ

3

От стандартного Docs 1,9 Выполнения программы,

4) Это положение иногда называют «как если бы» правило, поскольку реализация вольна игнорировать любые требования настоящего международного стандарта , пока результат будет таким, как если бы требование было соблюдено, насколько это можно определить из наблюдаемого поведения программы. Например, фактическая реализация не должна оценивать часть выражения, если она может вывести, что ее значение не используется и что никаких побочных эффектов, влияющих на наблюдаемое поведение программы , не производится.

Таким образом, это могло бы, да.

1

Короткий ответ: да. Довольно распространенный способ заставить регистрации должны сделать что-то вроде:

static bool foo = register_type(); 
+0

Есть ли способ заставить линкеры не игнорировать эти переменные? – excray

+3

@ user97642: в соответствующем блоке транслирования просто добавьте некоторую функцию. вызовите эту функцию. это может звучать как магия, но стандарт требует, чтобы статические переменные были инициализированы до этого вызова, поэтому он вводит зависимость. cheers & hth., –

+0

@Alf P. Steinbach, пустое использование, как 'def;' где-то недостаточно? Или требуется вызвать функцию из нее? – liaK

1

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

- Link объектный файл непосредственно, а чем положить его в библиотеку. (Это «стандартный» или «канонический» способ .)

- Используйте DLL. Невзирая на имя, DLL не являются библиотеками, а объектными файлами и связаны друг с другом в любом порядке.

- Создайте фиктивный глобальный символ и укажите его где-нибудь. (Часто это может быть автоматизировано и может быть предпочтительным решением , если вы поставляете библиотеку в качестве стороннего поставщика .)

+0

Хия Джеймс! :-) –

Смежные вопросы