Я испытываю очень странную проблему, используя gcc-4.7 (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2
, Я не могу скомпилировать следующий действительный код без предупреждения:
extern void dostuff(void);
int test(int arg1, int arg2)
{
int ret;
if (arg1) ret = arg2 ? 1 : 2;
dostuff();
if (arg1) return ret;
return 0;
}
Параметры компиляции и вывод:
$ gcc-4.7 -o test.o -c -Os test.c -Wall
test.c: In function ‘test’:
test.c:5:6: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]
Однако следующий код компилируется без предупреждения (хотя и с несколько менее эффективной сборкой):
extern void dostuff(void);
int test(int arg1, int arg2)
{
int ret;
if (arg1 && arg2) ret = 1;
if (arg1 && !arg2) ret = 2;
dostuff();
if (arg1) return ret;
return 0;
}
Я немного застрял и рассматриваю это как ошибку компилятора. Какие-нибудь мысли?
На самом деле это известная проблема в gcc.
gcc печально известен своими отчетами неверные неинициализированные переменные.
Недостатки были должным образом отмечены, и есть инициатива, чтобы преодолеть недостатки:
Лучшие неинициализированные предупреждения:
Коллекция компиляторов GNU предупреждает об использовании неинициализированных переменных с опцией
-Wuninitialized
, Однако текущая реализация имеет некоторые ощутимые недостатки. С одной стороны, некоторые пользователи хотели бы получать более подробные и последовательные предупреждения. С другой стороны, некоторые пользователи хотели бы получать как можно меньше предупреждений. Цель этого проекта — реализовать обе возможности, одновременно улучшая текущие возможности.
Инициатива направлена на предоставление более качественных предупреждений и приводит пример, аналогичный вашему. Соответствующая часть:
То, что пользователь понимает как ложное срабатывание, может отличаться для конкретного пользователя. Некоторых пользователей интересуют случаи, которые скрыты из-за действий оптимизаторов в сочетании с текущей средой. Однако многие пользователи этого не делают, поскольку этот случай скрыт, поскольку он не может возникнуть в скомпилированном коде. Канонический пример
int x;
if (f ())
x = 3;
return x;
где ‘f’ всегда возвращает ненулевое значение для текущей среды, и, таким образом, оно может быть оптимизировано. Здесь группа пользователей хотела бы получить неинициализированное предупреждение, поскольку «f» может возвращать ноль при компиляции в другом месте. Тем не менее, другая группа пользователей посчитает ложным предупреждение о ситуации, которая не может возникнуть в компилируемом исполняемом файле.
Других решений пока нет …