Pregunta

Al compilar mi proyecto con gcc y la opción -Wall, recibo una advertencia acerca de una declaración sin efecto en la última línea no existente de mi archivo flexible:

Advertencia:

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

Comando de Shell:

$ wc -l tokenizer.l
178 tokenizer.l

Última parte del archivo lex:

; {
    return SEMI;
}

¿Alguien sabe por qué podría recibir esta advertencia?

Si suprimo todas las directivas #line, el error es:

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

Que se refiere a la línea ECHO en:

case 30:
YY_RULE_SETUP
ECHO;
    YY_BREAK
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(inQuote):
case YY_STATE_EOF(inWord):
    yyterminate();
¿Fue útil?

Solución

En general, obtendrá ese error de cualquier regla lex que tenga un 'retorno' incondicional, porque flex termina generando un código similar (después de la expansión de macro):

case xxx:
    return SEMI;
    break;

El problema es que no se puede alcanzar el 'descanso'. Debe estar allí en caso de que su regla no regrese (por lo que el código no caerá en el código para el siguiente token, sino que continuará reconociendo el siguiente token). Flex no es lo suficientemente inteligente como para analizar realmente su código de regla y haga un análisis de flujo para determinar cuándo es innecesario el corte, por lo que siempre lo coloca allí. En general, el uso de -Wall en la salida de flex (o bison) le dará muchas advertencias como esta ...

Otros consejos

Creo que se siente que ; es una declaración sin efecto. Intenta citarlo:

";" {
    return SEMI;
}

Me encontré con el mismo problema y lo busqué un poco. Resultó que uno de mis " # incluye " en el archivo fuente flexible (el archivo .l) de alguna manera se incluyó indirectamente el archivo termios.h de la biblioteca estándar, que define una macro llamada " ECHO " (como " 0000010 "). El archivo fuente generado por flex por otro lado también quiere crear una macro llamada '' ECHO '', hay un '' #ifndef ECHO '' antes de que. Pero, por supuesto, con termios.h incluido, eso '' ifndef '' se evalúa como falso y ECHO no se definió según lo previsto. Eso llevó al error.

Explicación larga, solución corta: pongo

#ifdef ECHO
#undef ECHO
#endif

debajo de todas mis inclusiones en mi archivo .l, y eso funcionó.

Sé que este hilo de discusión ya es un poco antiguo, pero apareció primero cuando busqué en Google la advertencia, por lo que mi contribución aún podría ser útil para la gente.

Como dijeron las otras respuestas, el problema es que no se puede alcanzar un 'descanso' después de un 'retorno'.

Solía ??ser posible satisfacer a un compilador de que había una manera de llegar al 'descanso' fingiendo un retorno condicional:

if (1) return SEMI;

Tengo la sospecha de que algunos compiladores modernos son lo suficientemente inteligentes como para ver a través de esto, lo que en realidad es contraproducente para ellos. "Sí, tiene razón, Sr. Compiler, pero no puedo evitarlo así que STFU".

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top