Легкий способ найти неинициализированные переменные-члены
Я ищу простой способ найти неинициализированные переменные-члены класса.
Поиск их во время выполнения или времени компиляции в порядке.
В настоящее время у меня есть точка останова в конструкторе класса и поочередно проверяю переменные-члены.
Ответы
Ответ 1
Если вы используете GCC, вы можете использовать флаг -Weffc++
, который генерирует предупреждения, когда переменная не инициализируется в списке инициализации члена. Это:
class Foo
{
int v;
Foo() {}
};
Приводит к:
$ g++ -c -Weffc++ foo.cpp -o foo.o
foo.cpp: In constructor ‘Foo::Foo()’:
foo.cpp:4: warning: ‘Foo::v’ should be initialized in the member initialization list
Один недостаток заключается в том, что -Weffc++
также предупреждает вас, когда переменная имеет правильный конструктор по умолчанию и инициализацию, поэтому не требуется. Он также предупредит вас, когда вы инициализируете переменную в конструкторе, но не в списке инициализации члена. И он предупреждает о многих других проблемах стиля С++, таких как отсутствующие конструкторы-копии, поэтому вам может понадобиться немного очистить свой код, если вы хотите регулярно использовать -Weffc++
.
Существует также ошибка, которая приводит к тому, что она всегда дает вам предупреждение при использовании анонимных объединений, которые в настоящее время вы не можете обойти, а затем отключить предупреждение, что можно сделать с помощью
#pragma GCC diagnostic ignored "-Weffc++"
В целом, однако я обнаружил, что -Weffc++
невероятно полезен в улавливании множества распространенных ошибок С++.
Ответ 2
Valgrind может рассказать вам, есть ли в Linux.
Ответ 3
Valgrind (бесплатно, в Linux) и Purify (в Windows) найти неинициализированные переменные, недопустимые указатели и т.д., запустив свой код на специальной виртуальной машине.
Это прост в использовании и чрезвычайно мощный; он, вероятно, найдет много ошибок за пределами очевидных неинициализированных переменных.
Coverity, Klocwork и Lint может найти неинициализированные переменные, используя статический анализ кода.
Ответ 4
cppcheck найдет это.
Ответ 5
-Wuninitialized
?
(Это только проверяет, используется ли переменная неинициализирована, т.е. если
struct Q {
int x, y;
Q() : x(2) {}
int get_xy() const { return x*y; }
};
g++ будет предупреждать, только когда пользователь вызывает get_xy()
без назначения y
.)
Ответ 6
Visual Studio (MSVC) имеет параметр компилятора /sdl (Включить дополнительные проверки безопасности) (http://msdn.microsoft.com/en-us/library/jj161081.aspx). Во время выполнения это:
Выполняет инициализацию члена класса. Автоматически инициализирует класс члены типа указателя равны нулю при создании объекта (до конструктор работает). Это помогает предотвратить использование неинициализированных данных связанные с членами класса, что конструктор явно не инициализации.
Это не поможет вам обнаружить неинициализированные переменные-члены во время компиляции, но это делает поведение более предсказуемым, когда оно происходит во время выполнения. Вы, конечно, не должны писать код, который полагается на этот параметр.
Ответ 7
Если вы используете Visual Studio, вы можете скомпилировать ее в режиме отладки, остановить программу в отладчике и искать, какие переменные инициализируются байтами, содержащими 0xCC (стек) или 0xCD (куча).
Хотя лично я инвестировал в инструмент статического анализа для более тщательного подхода.
Ответ 8
/проанализировать в Visual Studio ( "Team System" )
Ответ 9
Осторожно! Варианты компилятора, предложенные здесь, не являются ни надежными, ни независимыми от версии. Рассмотрим простой пример:
class A {
int a;
public:
void mA() {
printf("haha");
++a;
int g = 2/a;
printf("%i\n",g);
}
};
int main() {
A a;
a.mA();
}
Скомпилировано с помощью g++ -O3 -Weffc++ -Wuninitialized
эта информация сообщает uninitialized
о версиях gcc до 4.6 включительно и успешно передается на 4.7 и 4.8 (проверена на MacPorts). Тогда, как ни странно, если мы удалим printf("haha");
, то как 4.7, так и 4.8 вдруг увидим uninitialized A::a
. Clang
немного лучше, поскольку он каким-то образом присваивает мусор (вместо удобного 0
) неинициализированным vars, так что вы видите их катастрофический эффект легче/раньше.
Мне не повезло в том, что вы заметили выше неинициализированный A::a
с помощью valgrind
; возможно, предложение, предлагающее valgrind
, может предоставить соответствующие варианты для определения этой ошибки.
Итог: большой вопрос, не очень надежные решения на данный момент... (как я его вижу).
Ответ 10
Clang с clang-analysis может это сделать. Это событие создаст хороший HTML-отчет, который указывает, когда доступ к неиспользуемой переменной.
Ответ 11
Рассмотрим следующий код
unint.cpp:
int main()
{
int a;
int b;
a++;
b = b + 5;
return 0;
}
Если код компилируется следующим комментарием, должны отображаться предупреждающие сообщения.
g++ -O3 -Wuninitialized unint.cpp
Примечание: для -Унициализации нужна опция -O3.