Подтвердить что ты не робот

Как предотвратить компиляцию моих "неиспользуемых" глобальных переменных?

Я использую статическую инициализацию, чтобы облегчить процесс регистрации некоторых классов с помощью factory в С++. К сожалению, я думаю, что компилятор оптимизирует "неиспользуемые" объекты, предназначенные для полезной работы в своих конструкторах. Есть ли способ сказать компилятору не оптимизировать глобальную переменную?

class SomeClass {
    public:
        SomeClass() {
            /* do something useful */
        }
};

SomeClass instance;

Моя точка останова в конструкторе SomeClass не попадает. В моем фактическом коде SomeClass находится в файле заголовка, и экземпляр находится в исходном файле, более или менее в одиночку.

РЕДАКТИРОВАТЬ: Как предполагал KJAWolf, этот код фактически скомпилирован в статическую библиотеку, а не в исполняемый файл. Его цель - зарегистрировать некоторые типы, также предоставляемые статическим lib со статическим списком типов и их создателями, для factory, чтобы потом читать из конструкции. Поскольку эти типы снабжены lib, добавление этого кода в исполняемый файл нежелательно.

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

4b9b3361

Ответ 1

Компилятор не может оптимизировать глобальные объекты.
Даже если они никогда не используются.

Что-то еще происходит в вашем коде.
Теперь, если вы создали статическую библиотеку с глобальным объектом и что глобальный объект не ссылается на исполняемый файл, он не будет втягиваться в исполняемый файл компоновщиком.

Ответ 2

Компилятор никогда не должен оптимизировать такие глобалы - если это так, он просто сломан.

Ответ 3

Чтобы построить Arthur Ulfeldt, volatile сообщает компилятору, что эта переменная может измениться за пределами знания компилятора. Я использовал его для размещения инструкции, позволяющей отладчику установить точку останова. Он также полезен для аппаратных регистров, которые могут изменяться в зависимости от среды или нуждаются в специальной последовательности. то есть регистр приема последовательного порта и определенные регистры сторожевого таймера.

Ответ 4

вы можете использовать

#pragma optimize off
int globalVar
#pragma optimize on

но я не знаю, работает ли это только в Visual Studio (http://msdn.microsoft.com/en-us/library/chh3fb0k(VS.80).aspx).

Вы также можете сказать, что компилятор вообще не оптимизирован, особенно если вы отлаживаете...

Ответ 5

Вы можете заставить этот один объект (ваш список типов) тянуть с ним другие объекты с помощью частичной привязки до создания полной статической библиотеки.

С GNU linker:

ld -Ur -o TypeBundle.o type1.o type2.o type3.o static_list.o
ld -static -o MyStaticLib.a type_bundle.o other_object.o another_object.o ...

Таким образом, всякий раз, когда статический список ссылается на код с использованием библиотеки, полный объект "TypeBundle.o" будет связан с результирующим двоичным кодом, включая type1.o, type2.o и type3.o.

В то время как на нем, проверьте значение "-Ur" в руководстве.

Ответ 6

Вы используете gcc с gdb? В прошлом была проблема, когда gdb не мог точно установить точки останова в конструкторах.

Кроме того, вы используете уровень оптимизации, который позволяет компилятору встроить методы в определение класса.

Ответ 7

У меня такая же настройка и проблема на VS2008. Я обнаружил, что если вы объявите класс с dllexport, он не будет оптимизирован.

class __declspec( dllexport ) Cxxx
{
.
}

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

Все оптимизации отключены (в режиме отладки), но это оптимизировано. Также волатильна/прагма оптимизирована. О глобальной переменной, созданной этим классом (в том же файле cpp) и т.д. Не работает.

Просто оказалось, что dllexport требует, по крайней мере, включить заголовочные файлы этих классов в другой файл cpp из exe для работы! Таким образом, только вариант состоит в том, чтобы добавить файл с вызовами к некоторым статическим членам для каждого класса и добавить этот файл во все проекты, используемые этими классами.

Ответ 9

Как насчет использования ключевого слова volatile? Это предотвратит слишком большую оптимизацию компилятора.