Declaração sem nenhum aviso efeito com o GCC e Flex / Bison
-
22-07-2019 - |
Pergunta
Ao compilar meu projeto com gcc ea opção -Wall, recebo um aviso sobre uma declaração sem efeito na última linha inexistente do meu arquivo flex:
Aviso:
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 de comando:
$ wc -l tokenizer.l
178 tokenizer.l
Última parte do arquivo lex:
; {
return SEMI;
}
Alguém sabe por que eu poderia estar recebendo esse aviso?
Se eu suprimir todas as directivas #line, o erro é:
lex.yy.c: In function ‘yylex’:
lex.yy.c:1021: warning: statement with no effect
que se refere à linha ECHO em:
case 30:
YY_RULE_SETUP
ECHO;
YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(inQuote):
case YY_STATE_EOF(inWord):
yyterminate();
Solução
Em geral, você vai ter que o erro de qualquer regra lex que tem um 'retorno' incondicional nele, porque extremidades flexíveis até gerar código que se parece com (após expansão de macro):
case xxx:
return SEMI;
break;
O problema é que o 'break' está inacessível. Ele precisa estar lá no caso de sua regra de não voltar (para que o código não vai cair até o código para o próximo token, mas em vez disso, passar a reconhecer o próximo token.) Flex não é inteligente o suficiente para realmente parse seu código regra e fazer análise de fluxo para determinar quando a ruptura é desnecessário, por isso só sempre coloca-lo lá. Em geral, usando -Wall na saída do cabo flexível (ou bison) vai dar-lhe lotes de avisos como este ...
Outras dicas
Eu acho que ele se sente que ;
é uma declaração sem efeito. Tente citando-a:
";" {
return SEMI;
}
Eu corri para o mesmo problema e parecia um pouco para ele. Descobriu-se que um dos meus "#includes" no arquivo de origem Flex (o arquivo .l) de alguma forma indiretamente incluído o arquivo de biblioteca termios.h padrão, que define uma macro chamada "ECHO" (como "0000010"). O arquivo de origem gerado pelo Flex, por outro lado, também quer criar uma macro chamada "ECHO", há um "#ifndef ECHO" antes disso. Mas, claro, com termios.h incluído, que "ifndef" avalia a falsa e ECHO não foi definido como pretendido. Que levou ao erro.
explicação longa, curta solução: Eu coloquei
#ifdef ECHO
#undef ECHO
#endif
abaixo todas as minhas inclui no meu arquivo .l, e que fez o truque.
Eu sei que esta linha de discussão já está um pouco velho, mas acabou-se pela primeira vez quando eu pesquisei o aviso, por isso a minha contribuição ainda pode ser útil para as pessoas.
Como as outras respostas disse, o problema é que um 'break' depois de um 'retorno' não pode ser alcançado.
É usado para ser possível satisfazer um compilador que havia uma maneira de chegar ao 'break' por simular um retorno condicional:
if (1) return SEMI;
Eu tenho uma suspeita de que alguns compiladores modernos são inteligentes o suficiente para ver através deste - que na verdade é contra-produtiva deles. "Sim, você está certo, Sr. Compiler, mas não posso evitá-lo tão STFU".