Я знаю, что 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 ++, который заставил бы его заполнить память, которая, как в стандарте было бы иначе сказано, должна быть неинициализированной?
Я не думаю, что такая опция / функция существует в gcc / g ++.
Например, все глобальные (и статические) переменные находятся в разделе .bss
, который всегда инициализируется нулями. Однако неинициализированные файлы помещаются в специальный раздел внутри .bss
для совместимости.
Если вы хотите, чтобы они тоже были обнулены, вы можете передать компилятору аргумент -fno-common
. Или, если вам это нужно для каждой переменной, используйте __ attribute__ ((nocommon))
.
Для кучи можно написать собственный распределитель для выполнения того, что вы описали. Но для стека я не думаю, что есть простое решение.
Любой компилятор C ++ может инициализировать любой тип POD его «нулевым» значением, используя синтаксис:
int i = int();
float f = float();
MyStruct mys = MyStruct();
// and generally:
T t = T();
Если вы хотите поговорить об отладке, это что-то еще. ..
(Кстати, я думаю, что VS имел всю неинициализированную память, инициализированную 0xCC в «режиме отладки, так что независимо от того, куда вы прыгаете (например, вызываете неверный указатель на функцию), это не так» Это реальный программный код / данные int3 подняты.)
Я не верю, что g ++ обнаружит все подобные случаи, но Valgrind определенно обнаружит.