tag - jstl core
¿Qué sentido tienen estas advertencias de variables aplastadas? (2)
Tengo una función como esta:
#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int x)
{
if (setjmp(buf))
return;
if (some_global)
x += 5;
func2(x);
}
GCC (gcc (Debian 4.4.5-8) 4.4.5) da una advertencia:
test.c: In function ‘func’: test.c:5: warning: argument ‘x’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
¿¿¿¿Por qué???? Quiero decir, obviamente no me importa si x
está obstruida o no, porque no puede usarse después de que setjmp
regrese. Incluso el compilador debe ser consciente de algo tan cegadoramente obvio, dado que tiene algún tipo de conocimiento especial de setjmp
.
Mi interés principal es encontrar errores en una base de código que heredé, por lo que "usar este estilo de codificación en su lugar" no es un consejo que estoy buscando. Sin embargo, hay una serie de giros extraños aquí. Por ejemplo, si x
es una variable local en lugar de un parámetro, GCC no se queja. Además, GCC no se quejará sin la línea if (some_global)
. Bonito. Algo está arruinando el análisis de flujo de GCC, o tal vez GCC sabe algo que yo no.
Asi que,
¿Hay una manera fácil de suprimir esta advertencia para esta función, de la misma manera que puede convertir los parámetros no utilizados en
(void)
?¿O simplemente suprimo la advertencia de todo el proyecto?
¿O me estoy perdiendo algo?
Actualización: Permítame compartir con usted una versión ligeramente diferente que no genera una advertencia:
#include <setjmp.h>
jmp_buf buf;
void func2(int g);
extern int some_global;
void func(int y)
{
int x = y;
if (setjmp(buf))
return;
if (some_global)
x += 5;
func2(x);
}
De man longjmp
:
Los valores de las variables automáticas no se especifican después de una llamada a longjmp () si cumplen con todos los criterios siguientes:
· they are local to the function that made the corresponding setjmp(3)
call;
· their values are changed between the calls to setjmp(3) and
longjmp(); and
· they are not declared as volatile.
A medida que sucede, su variable x
en el primer ejemplo cumple con los criterios:
- Es local para la función, ya que los parámetros de la función son como las variables locales automáticas.
- Su valor puede cambiarse justo después de
setjmp
sisome_global
es verdadero. - No es volátil.
Por lo tanto, su valor puede no estar especificado (saturado).
Sobre por qué la segunda versión no emite la advertencia ... ni idea.
Después de raspar un poco la red y releer los documentos de GCC, encontré esto:
Atributos de la función:
returns_twice
El atributo
returns_twice
le dice al compilador que una función puede devolver más de una vez. El compilador se asegurará de que todos los registros estén muertos antes de llamar a una función de este tipo y emitirá una advertencia sobre las variables que se pueden eliminar después del segundo retorno de la función. Ejemplos de tales funciones sonsetjmp
yvfork
. La contraparte similar alongjmp
de dicha función, si la hubiera, podría tener que estar marcada con el atributonoreturn
.
Así que parece que GCC no tiene ningún "conocimiento especial" de setjmp
, simplemente insinúa que sí. Todo lo que sabe es que setjmp
devuelve dos veces, no que siempre devuelva 0 la primera vez y luego que no sea cero. Dios mío, eso hubiera sido bueno.