2010-04-16 2 views
9

Я знаю, что Visual Studio под вариантами отладки заполнит память известным значением. Действительно ли g ++ (любая версия, но gcc 4.1.2 наиболее интересна), есть ли какие-либо опции, которые бы заполнили неинициализированную локальную структуру POD с узнаваемыми значениями?Может ли g ++ заполнить неинициализированные переменные POD с известными значениями?

struct something{ int a; int b; }; 
void foo() { 
    something uninitialized; 
    bar(uninitialized.b); 
} 

Ожидается, что uninitialized.b будет непредсказуемым случайностью; явно ошибка и легко найти , если оптимизация и предупреждения включены. Но скомпилировано только с -g, нет предупреждение. У коллеги был случай, когда код, подобный этому, работал, потому что по совпадению имел действительное значение; когда компилятор обновился, он начал сбой. Он думал, что это связано с тем, что новый компилятор вводил известные значения в структуру (так же, как VS заполняет 0xCC). По моему собственному опыту, это было просто отличное от случайных значений, которые не были действительными.

Но теперь мне любопытно - есть ли какие-либо настройки g ++, которые заставляют его заполнять память, которую стандарт в противном случае сказал бы, должен быть неинициализирован?

ответ

3

Я не думаю, что такая опция/функция существует в gcc/g ++.

Например, все глобальные (и статические) переменные находятся в разделе .bss, который всегда инициализируется нулями. Тем не менее, неинициализированные, помещаются в специальный раздел в пределах .bss для обеспечения совместимости.

Если вы хотите, чтобы их тоже обнуляли, вы можете передать аргумент -fno-common компилятору. Или, если вам это нужно на основе переменной, используйте __attribute__ ((nocommon)).

Для кучи, вы можете написать свой собственный распределитель, чтобы выполнить то, что вы описали. Но для стека я не думаю, что есть простое решение.

+0

Я не думал, что функция существует, но руководство gcc длинное и глубокое, и я был удивлен тем, что там скрыто раньше. –

1

Я не верю, что g ++ обнаружит все случаи, подобные этому, но Valgrind обязательно будет.

+0

Да, другие инструменты анализа, похоже, являются решением. Казалось, что компилятор может организовать, но не слишком удивительно, если это не так. –

4

Любой C++ comiler может инициализировать любой тип POD к его «нулевой» величины, используя следующий синтаксис:

int i = int(); 
float f = float(); 
MyStruct mys = MyStruct(); 
// and generally: 
T t = T(); 

Если вы хотите поговорить об отладке, что-то еще ...

(Кстати , Я думаю, что VS имел все неинициализированная память инициализировалась до 0xCC, когда в режиме «отладки», так что независимо от того, где вы прыгаете (например, вызываете плохой указатель на функцию), это не так, а реальный программный код/​​данные int3 подняты.)

+4

Или, для тех, кто хочет сделать C++ похожим на Lisp, 'T t ((T()))' :-) –

+1

@James: Вы абсолютно правы, но этот синтаксис ставит меня в дилемму. Я не знаю, что больнее смотреть на нее - мои глаза или мое сердце. :) – conio

+0

Да, он * может * инициализировать, но это не так, поэтому я думаю, что я действительно склонен к отладочной помощи. Похоже, что решение лежит за пределами g ++, хотя (valgrind et.al). –