J'ai débogué une étrange erreur de compilation que j'obtenais dans mon code, et j'ai fini par découvrir que je ne pouvais pas utiliser le préfixe si_
pour certains noms de variables (de tout type) si <signal.h>
est inclus.
Voici un exemple de code source très simple qui reproduit le problème:
#include <signal.h>
int main(void)
{
int si_value = 0;
return 0;
}
Si j'essaye de compiler ceci avec le compilateur GNU C gcc
, j'obtiens l'erreur suivante:
> 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
Néanmoins, si j'utilise un autre nom tel que si_value2
, l'erreur n'apparaît pas. Comme référence, j'utilise GCC v7.3.0 sur Ubuntu Mate 18.04.1 LTS. Le même problème est observé avec g++
.
Je suppose que ce comportement est dû à une définition de macro à l'intérieur du <signal.h>
en-tête, mais après l'avoir parcouru brièvement, je n'arrivais pas à trouver quoi que ce soit de vraiment lié.
Honnêtement, je peux le réparer en utilisant simplement un autre nom. Cependant, ma préoccupation est: comment pourrais-je éviter avec élégance ce type de problème à l'avenir?
Mise à jour: Comme @ F.X. a suggéré, en utilisant gcc -E example.c
montre que le nom de la variable est développé (d'où l'erreur):
...
int
# 6 "example.c" 3 4
_sifields._rt.si_sigval
# 6 "example.c"
= 0;
...
<signal.h>
n'empêche pas réellement d'utiliser si_
comme préfixe sur vos variables. Cependant, la spécification POSIX indique que ce préfixe est réservé, afin de permettre à l'en-tête et aux fonctions de bibliothèque qu'il déclare d'utiliser ces noms, sans avoir à craindre qu'ils n'entrent en conflit avec vos propres variables.
Donc, ce qui se passe ici, c'est que si_value
est défini d'une manière ou d'une autre dans le fichier d'en-tête, peut-être en tant que macro ou typedef, et votre tentative d'utiliser le même nom est en conflit avec cela. Si vous avez utilisé si_vy1ghad563nvy43wd
cela fonctionnerait probablement, mais théoriquement l'en-tête pourrait utiliser ce nom (pensant qu'il serait peu probable qu'il entre en conflit avec tout ce qu'un programmeur d'applications utiliserait).
C n'a pas de vrais espaces de noms, donc les conventions de dénomination comme celle-ci sont utilisées comme un simple substitut.
comment pourrais-je éviter avec élégance ce type de problèmes à l'avenir?
Vous vérifiez certains documentation pour les en-têtes que vous utilisez et évitez les noms qui sont documentés comme réservés.