2

使用 gcc 和 -Wall 选项编译我的项目时,我收到一条警告,提示我的 flex 文件最后一行不存在的语句无效:

警告:

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();
4

4 回答 4

5

通常,您会从其中包含无条件“返回”的任何 lex 规则中得到该错误,因为 flex 最终生成的代码看起来像(在宏扩展之后):

case xxx:
    return SEMI;
    break;

问题是“中断”是无法到达的。它需要在那里以防您的规则不返回(因此代码不会落入下一个令牌的代码,而是会继续识别下一个令牌。)Flex 不够聪明,无法实际解析您的规则代码并进行流分析以确定何时不需要中断,因此它总是将其放在那里。一般来说,在 flex(或 bison)的输出上使用 -Wall 会给你很多这样的警告......

于 2009-10-30T19:09:22.037 回答
2

我想这感觉;是一个没有效果的声明。尝试引用它:

";" {
    return SEMI;
}
于 2009-10-30T12:59:13.530 回答
1

我遇到了同样的问题,并对其进行了一些研究。事实证明,我在 flex 源文件(.l 文件)中的一个“#includes”以某种方式间接包含了标准库 termios.h 文件,该文件定义了一个名为“ECHO”的宏(如“0000010”)。另一方面,flex生成的源文件也想创建一个名为“ECHO”的宏,在此之前有一个“#ifndef ECHO”。但是,当然,在包含 termios.h 的情况下,“ifndef”的计算结果为 false,并且 ECHO 没有按预期定义。这导致了错误。

长解释,短解决方案:我把

#ifdef ECHO
#undef ECHO
#endif

在我的 .l 文件中包含的所有内容下方,这就是诀窍。

我知道这个讨论线程已经有点老了,但是当我用谷歌搜索警告时它首先出现了,所以我的贡献可能仍然对人们有用。

于 2013-03-05T10:16:36.650 回答
0

正如其他答案所说,问题在于“返回”后无法达到“休息”。

过去可以通过伪造条件返回来满足编译器的要求:

if (1) return SEMI;

我怀疑一些现代编译器足够聪明,可以看穿这一点——这实际上适得其反。“是的,你是对的,编译器先生,但我无法避免它,所以 STFU”。

于 2009-10-31T13:43:48.880 回答