GCCおよびFlex / Bisonを使用した効果警告なしのステートメント
-
22-07-2019 - |
質問
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();
解決
一般的に、flexは(マクロ展開後)次のようなコードを生成するため、無条件の 'return'を持つlexルールからそのエラーが発生します:
case xxx:
return SEMI;
break;
問題は、「ブレーク」に到達できないことです。ルールが返されない場合に必要です(したがって、コードは次のトークンのコードに落ちませんが、代わりに次のトークンを認識します)。ルールコードを作成し、フロー分析を行って、いつブレークが不要になるかを判断し、常にそこに配置します。一般に、flex(またはbison)の出力で-Wallを使用すると、このような多くの警告が表示されます...
他のヒント
;
は効果のないステートメントであると感じています。引用してみてください:
";" {
return SEMI;
}
私は同じ問題にぶつかり、少し調べました。私の「#includes」の1つが判明しました。 flexソースファイル(.lファイル)には、「ECHO」という名前のマクロを定義する標準ライブラリtermios.hファイルが何らかの形で間接的に含まれています。 (「0000010」として)。 一方、flexによって生成されたソースファイルは、「ECHO」という名前のマクロを作成することも望んでおり、「#ifndef ECHO」があります。それ以前は。しかしもちろん、termios.hが含まれていると、その「ifndef」はfalseと評価され、ECHOは意図したとおりに定義されませんでした。それがエラーにつながりました。
長い説明、短い解決策:私は次のように述べました
#ifdef ECHO
#undef ECHO
#endif
.lファイルに含まれるすべてのインクルードの下で、それでうまくいきました。
このディスカッションスレッドは既に少し古いことを知っていますが、警告をグーグルで検索したときに最初に表示されたので、私の貢献はまだ人々に役立つかもしれません。
他の回答が言ったように、問題は「戻る」後の「ブレーク」に到達できないことです。
以前は、条件付きリターンを偽造することで「ブレーク」に到達する方法があったことをコンパイラに満足させることが可能でした。
if (1) return SEMI;
最近のコンパイラーの中には、これを見抜くのに十分賢いものがあるという疑いがあります-実際には逆効果です。 "はい、あなたは正しいです、Mr Compiler、しかし私はそれを避けることができませんので、STFU"。