C ++ Глобальные переменные класса не создаются - PullRequest
4 голосов
/ 18 ноября 2010

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

В файле Keywords.cpp

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

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

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

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

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

*

} * 1013

Ответы [ 3 ]

3 голосов
/ 18 ноября 2010

Из стандартных документов 1.9 Выполнение программы ,

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

Итак, это может , да.

1 голос
/ 18 ноября 2010

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

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

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

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

1 голос
/ 18 ноября 2010

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

static bool foo = register_type();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...