compilar - compile c++ linux terminal
¿Por qué<signal.h> evita el uso de "si_" como prefijo para el nombre de algunas variables? (2)
¿Cómo podría evitar este tipo de problemas con elegancia en el futuro?
Verifica la documentation de los encabezados que está utilizando y evita los nombres que están documentados como reservados.
He estado depurando un extraño error de compilación que estaba recibiendo dentro de mi código, y terminé descubriendo que no puedo usar el prefijo si_
para algunos nombres de variables (de cualquier tipo) si se incluye <signal.h>
.
Aquí hay un ejemplo de código fuente muy simple que reproduce el problema:
#include <signal.h>
int main(void)
{
int si_value = 0;
return 0;
}
Si intento compilar esto con el compilador GNU C gcc
, obtengo el siguiente error:
> gcc example.c
In file included from /usr/include/signal.h:57:0,
from example.c:2:
example.c: In function ‘main’:
example.c:6:9: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
int si_value = 0;
^
example.c:6:9: error: expected expression before ‘.’ token
No obstante, si uso otro nombre como si_value2
, el error no aparece. Como referencia, estoy usando GCC v7.3.0 en Ubuntu Mate 18.04.1 LTS. El mismo problema se observa con g++
.
Supongo que este comportamiento se debe a alguna definición de macro dentro del encabezado <signal.h>
, pero después de analizarlo brevemente, no pude encontrar nada realmente relacionado.
Honestamente puedo arreglarlo simplemente usando otro nombre. Sin embargo, mi preocupación es: ¿cómo podría evitar elegantemente este tipo de problema en el futuro?
Actualización: como @FX ha sugerido, el uso de gcc -E example.c
muestra que el nombre de la variable está expandido (de ahí el error):
...
int
# 6 "example.c" 3 4
_sifields._rt.si_sigval
# 6 "example.c"
= 0;
...
<signal.h>
realidad no evita el uso de si_
como prefijo en sus variables. Sin embargo, la especificación POSIX establece que este prefijo está reservado, para permitir que el encabezado y las funciones de biblioteca declaren usar estos nombres, sin tener que preocuparse de que entren en conflicto con sus propias variables.
Entonces, lo que está sucediendo aquí es que si_value
está definido de alguna manera en el archivo de encabezado, tal vez como una macro o typedef, y su intento de usar el mismo nombre entra en conflicto con esto. Si usó si_vy1ghad563nvy43wd
, probablemente funcionaría, pero en teoría el encabezado podría usar ese nombre (pensando que sería improbable que entren en conflicto con cualquier cosa que un programador de aplicaciones usaría).
C no tiene espacios de nombres reales, por lo que las convenciones de nomenclatura de este tipo se utilizan como un simple sustituto.