views:

548

answers:

3

When compiling my project with gcc and the -Wall option, I get a warning about a statement with no effect in the non-existant last line of my flex file:

Warning:

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

Shell Command:

$ wc -l tokenizer.l
178 tokenizer.l

Last part of lex file:

; {
    return SEMI;
}

Anyone know why I might be getting this warning?

If I suppress all #line Directives, the error is:

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

Which refers to the ECHO line in:

case 30:
YY_RULE_SETUP
ECHO;
    YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(inQuote):
case YY_STATE_EOF(inWord):
    yyterminate();
+2  A: 

I guess it feels that ; is a statement with no effect. Try quoting it:

";" {
    return SEMI;
}
Magnus Hoff
Had already tried that.. but thanks :-)
Kyle Brandt
I should also add I haven't seen any signs of anything wrong because of this warning.
Kyle Brandt
+4  A: 

In general, you'll get that error from any lex rule that has an unconditional 'return' in it, because flex ends up generating code that looks like (after macro expansion):

case xxx:
    return SEMI;
    break;

The problem being that the 'break' is unreachable. It needs to be there in case your rule does not return (so the code won't fall through to the code for the next token, but will instead go on to recognize the next token.) Flex isn't smart enough to actually parse your rule code and do flow analysis to determine when the break is unneeded, so it just always puts it there. In general, using -Wall on the output of flex (or bison) will give you lots of warnings like this...

Chris Dodd
What is an unconditional return? In this case, the ECHO macro seems to be do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) //So does this apply? So is there really no need for -Wall when compiling flex or Bison's output files into objects?
Kyle Brandt
An 'unconditional return' is a 'return' that's not part of an 'if', so it will always be executed if the 'case' matches.
Chris Dodd
A: 

As the other answers said, the trouble is that a 'break' after a 'return' can't be reached.

It used to be possible to satisfy a compiler that there was a way to get to the 'break' by faking a conditional return:

if (1) return SEMI;

I have a suspicion that some modern compilers are clever enough to see through this - which is actually counter-productive of them. "Yes, you're right, Mr Compiler, but I can't avoid it so STFU".

Jonathan Leffler