Subtilités sur les unions
D'apres ce que je comprends du livre "Le langage C" une union peut contenir plusieurs mais seul le dernier champ écrit est valide :
Code:
1 2 3 4 5
|
union {
int val1;
float val2;
} u; |
Dans l'union précédente seule val1 ou val2 est valide à un instant donné. Jusque la je comprends.
Maintenant je vais donner un cas que je comprends pas... Voici une union (pour ceux qui connaissent (linux/netfilter_ipv6/ip6_tables.h) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
struct ip6t_entry_match
{
union {
struct {
u_int16_t match_size;
/* Used by userspace */
char name[IP6T_FUNCTION_MAXNAMELEN-1];
u_int8_t revision;
} user;
struct {
u_int16_t match_size;
/* Used inside the kernel */
struct ip6t_match *match;
} kernel;
/* Total length */
u_int16_t match_size;
} u;
unsigned char data[0];
}; |
Voici un code écrivant dans cette union (adapté de ip6tables.c pour les connaisseurs aussi :)):
Code:
1 2 3 4 5
|
struct ip6t_entry_match m;
m.u.match_size = size;
strcpy(m.u.user.name, name);
set_revision(m.u.user.name, revision); |
Et la... C'est le drame !
Ce code ne devrait pas selon ce que j'ai compris faire ce que le programmeur souhaitait faire (marrante cette tournure de phrase ...), à savoir écrire dans la variable match_size de l'union ET dans la structure user de l'union. Selon moi, une fois que l'on a écrit dans la structure user, la valeur contenue dans match_size ne doit plus être valide.
Or ce n'est pas le cas, la valeur contenue dans match_size est toujours valide et égale à l'affectation précédente (vive printf) !
Quelqu'un a une explication a me donner pour ça ? (J'ai ma petite idée mais je me la réserve :))
P.S : Si ca se trouve c'est gros comme le nez au milieu de la figure et que je suis fatigué par une journée de relecture de code iptables ;)