Алгоритм, который диагностирует неинициализированные переменные без ложных негативов или позитивов, должен (в качестве подпрограммы) включать алгоритм, который решает проблему остановки .Что означает , такого алгоритма нет . невозможно для компьютера, чтобы сделать это правильно 100% времени.
Я не знаю, как именно работает анализ неинициализированных переменных GCC, но я знаю, что он очень чувствителен к тому, чторанние этапы оптимизации сделали с кодом.Так что я совсем не удивлен, что иногда вы получаете ложные срабатывания.Он отличает случаи, когда он определен, от случаев, когда он не может быть определен -
int foo() { int a; return a; }
выдает «предупреждение:« a » используется неинициализированным в этой функции» (выделено мое).
РЕДАКТИРОВАТЬ: Я обнаружил случай, когда последние версии GCC (4.3 и более поздние версии) не удалось диагностировать неинициализированную переменную:
int foo(int x)
{
int a;
return x ? a : 0;
}
Ранние оптимизации отмечают, что если x
не равен нулю, поведение функции не определено, поэтому они предполагают, что x
должно быть равно нулю и заменяют весь текст функции на "return 0;
". Это происходитзадолго до прохода, который генерирует использованные неинициализированные предупреждения, поэтому диагностики нет.См. ошибка GCC 18501 для подробностей.
Я приведу это частично, чтобы продемонстрировать, что производственные компиляторы могут неправильно диагностировать неинициализированные переменные в обоих направлениях, а частично, потому что это хороший примерДело в том, что неопределенное поведение может распространяться назад во время выполнения.В тестировании x
нет ничего неопределенного, но поскольку код, зависящий от элемента управления x
, имеет неопределенное поведение, компилятору разрешается предполагать, что зависимость элемента управления никогда не выполняется, и отбрасывать тест.