Может ли g ++ заполнить неинициализированные переменные POD известными значениями? - PullRequest
9 голосов
/ 16 апреля 2010

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

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

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

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

Ответы [ 3 ]

4 голосов
/ 16 апреля 2010

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

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

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

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

3 голосов
/ 16 апреля 2010

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

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

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

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

1 голос
/ 16 апреля 2010

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

...