Вопрос

При компиляции моего проекта с помощью gcc и опции -Wall я получаю предупреждение об утверждении без эффекта в несуществующей последней строке моего гибкого файла:

Внимание:

gcc -Wall -O0 -ggdb3 -DNOSUDO -DJOBC -DDEBUG -c lex.yy.c
tokenizer.l: In function ‘yylex’:
tokenizer.l:179: warning: statement with no effect

Команда оболочки:

$ wc -l tokenizer.l
178 tokenizer.l

Последняя часть файла lex:

; {
    return SEMI;
}

Кто-нибудь знает, почему я могу получить это предупреждение?

Если я подавлю все директивы #line, ошибка будет следующей:

lex.yy.c: In function ‘yylex’:
lex.yy.c:1021: warning: statement with no effect

Который ссылается на строку ECHO в:

case 30:
YY_RULE_SETUP
ECHO;
    YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(inQuote):
case YY_STATE_EOF(inWord):
    yyterminate();
Это было полезно?

Решение

В общем, вы получите эту ошибку из любого правила lex, в котором есть безусловный возврат, потому что flex в итоге генерирует код, который выглядит (после расширения макроса):

case xxx:
    return SEMI;
    break;

Проблема в том, что «разрыв» недоступен. Оно должно быть там на случай, если ваше правило не вернется (поэтому код не попадет в код для следующего токена, а вместо этого продолжит распознавать следующий токен.) Flex не достаточно умен, чтобы фактически анализировать код вашего правила и анализ потока, чтобы определить, когда перерыв не нужен, поэтому он всегда помещает его туда. В общем, использование -Wall на выходе flex (или bison) даст вам много предупреждений, подобных этому ...

Другие советы

Мне кажется, что ; - это заявление без эффекта. Попробуйте процитировать это:

";" {
    return SEMI;
}

Я столкнулся с той же проблемой и немного ее изучил. Оказалось, что один из моих "# включает в себя" в исходный файл flex (файл .l) каким-то образом косвенно включен файл стандартной библиотеки termios.h, в котором определен макрос с именем «ECHO»; (как "0000010"). С другой стороны, исходный файл, сгенерированный с помощью flex, также хочет создать макрос с именем «ECHO», в котором есть «#ifndef ECHO»; до этого. Но, конечно, с включенным termios.h, это "ifndef" оценивается как ложное и ECHO не было определено как задумано. Это привело к ошибке.

Длинное объяснение, короткое решение: я положил

#ifdef ECHO
#undef ECHO
#endif

ниже всех моих включений в мой файл .l, и это помогло.

Я знаю, что эта ветка обсуждения уже немного устарела, но она появилась первой, когда я погуглил предупреждение, поэтому мой вклад все еще может быть полезен для людей.

Как говорилось в других ответах, проблема в том, что «перерыв» после «возврата» не может быть достигнут.

Раньше было возможно убедить компилятор в том, что есть способ добраться до 'break' путем фальсификации условного возврата:

if (1) return SEMI;

У меня есть подозрение, что некоторые современные компиляторы достаточно умны, чтобы видеть сквозь это - что на самом деле контрпродуктивно с их стороны. " Да, вы правы, мистер Компилятор, но я не могу избежать этого, так что STFU ".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top