gcc сообщает "никогда не будет выполнено" о строке: while(fgets(line, MAX_LINE, stdin)!= NULL)
Я ищу объяснение, почему gcc
дают это предупреждение для меня.
Я собираю с gcc-3
на cygwin
с -Wunreachable-code
флаг, и GCC говорит это предупреждение для меня:
main.c: 223: предупреждение: никогда не будет выполнено
Вот эта строка: while(fgets(line, MAX_LINE, stdin) != NULL) {
Этот код находится внутри if(exp) { }
блок где exp
динамически устанавливается в соответствии с аргументами командной строки (анализируется getopt()
), посмотрите на часть кода:
if(mystruct.hastab) {
значение по умолчанию 0
, Но это стало 1
если -t
флаг передается приложению, как вы можете видеть по следующему адресу:
struct mystruct_t {
//...
int hastab;
} mystruct;
int main(int argc, char *argv[])
{
int opt;
memset(&mystruct, 0, sizeof(mystruct));
while((opt = getopt(argc, argv, optString)) != -1) {
switch(opt) {
case 't':
mystruct.hastab = 1;
break;
//....
}
}
proc();
return 0;
}
void
proc(void)
{
char *buf, *tmpbuf, line[MAX_LINE + 1], *p, *fullfilename;
if(mystruct.hastab) {
while(fgets(line, MAX_LINE, stdin) != NULL) {
//...
}
} else {
//...
}
}
Итак, есть причина для выполнения кода. Как бывает.
3 ответа
Вот еще одна возможность: проблема с макросами. Вот простой пример, который демонстрирует вашу ошибку:
#include <string.h>
int s;
int main(int argc, char *argv[]) {
memset(&s, 0, sizeof(s));
}
Когда я компилирую это, я получаю:
$ gcc -Wunreachable-code tmp.c
tmp.c: In function ‘main’:
tmp.c:4: warning: will never be executed
Ошибка не особенно поучительна. Однако, если вы запустите препроцессор, посмотрите, что memset
расширяется до:
$ gcc -E tmp.c
...
int s;
int main(int argc, char *argv[]) {
((__builtin_object_size (&s, 0) != (size_t) -1) ? __builtin___memset_chk (&s, 0, sizeof(s), __builtin_object_size (&s, 0)) : __inline_memset_chk (&s, 0, sizeof(s)));
}
Я подозреваю, из-за постоянного размера s
только одна из ветвей ?:
когда-либо выполняется, и это то, на что жалуется GCC. В вашем случае, это, вероятно, fgets
это макрос. Бежать gcc -E
найдите в выходной строке свою проблему и посмотрите, не шатается ли она (у меня нет, но я не запускаю cygwin).
Мораль истории: препроцессоры и макросы сосут.
Похоже, GCC убежден hastab
никогда не устанавливается или устанавливается только после кода, о котором предупреждает. Конечно, кажется, что gcc не прав, но так как вы дали нам только фрагменты, трудно быть уверенным. Я не думаю, что кто-то может помочь вам дальше, если мы не увидим полную программу, которую мы можем составить сами.
Если бы мне пришлось угадывать, я бы сказал, что gcc рассматривает 2 случая, когда вы можете позвонить proc()
не задав mystruct.hastab
к чему-то другому, чем 0
,
Первый случай, если это соответствует false
при первом запуске, так как вы будете выпадать из цикла без выполнения switch
заявление:
while((opt = getopt(argc, argv, optString)) != -1) {
Второй случай, если opt
никогда 't'
:
switch(opt) {
case 't':
mystruct.hastab = 1;
Таким образом, вы выпадете из цикла, даже не ставя mystruct.hastab
к ненулевому значению.