У меня возникла очень странная проблема с использованием 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;
}
Я несколько застрял и считаю это ошибкой компилятора. Какие-нибудь мысли?
ret == arg2 ? 1 : 2;
?? - person Alok Save   schedule 03.01.2013arg1=0, arg2=0
, вернуть 1, еслиarg1=1, arg2=1
, вернуть 2, еслиarg1=1, arg2=0
. Этот фрагмент представляет собой упрощенный случай гораздо более серьезной проблемы, с которой я сталкиваюсь. - person user593062   schedule 03.01.2013volatile
также решает проблему, но на самом деле это не идеально. - person user593062   schedule 03.01.2013int ret;
не означаетret == 0
. Если вы изменитеint ret = 0;
, это должно решить вашу проблему и также правильно вписаться в вашу логику. Код, который у вас есть в настоящее время, не инициализируетret
в0
.ret
имеет неопределенное значение, поскольку это локальная/автоматическая переменная, которая не инициализирована явно. Но это не отвечает на основную аномалию. - person Alok Save   schedule 03.01.2013ret
— это большой массив, который я не хочу инициализировать, если он не используется. Глядя на мою первую программу, ret действительно никогда не используется неинициализированным, поэтому предупреждение неверно, не так ли? - person user593062   schedule 03.01.2013ret
, либо не инициализируется, но при этом вообще никогда не используетret
. Ваше возражение неверно, код, показанный выше, наверняка никогда не получит доступ кret
до его инициализации, явная нулевая инициализация не требуется, и если компилятор заявляет что-то еще, он не работает. - person Mecki   schedule 24.12.2020