Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Passage d'arguments par valeur et padding

4 réponses
Avatar
none
Bonjour,

Récemment, j'ai été confronté au problème suivant (architecture 64bits).
Soit le type Type :

typedef struct { int a; void * b } Type;

Sans optimisation, on a généralement sizeof(Type) = 16. Il y a 4 octets
d'alignement entre 'a' et 'b'.

J'avais pris l'habitude de systématiquement initialiser mes instance de
Type par un bzero() bien senti. Je pouvais ainsi les comparer à coup de
memcmp, puisque les octets d'alignement étaient a priori toujours à 0.

Cependant, je me suis rendu compte récemment que les versions récentes
de gcc (4.1.2 et 4.3.2) empilaient les structures champ par champ plutôt
que l'intégralité des instances lors du passage d'argument par valeur.
Il se peut donc que dans la fonction appelée, les octets d'alignement de
l'instance une fois dépilée ne soient pas à 0.

Est-ce que la norme C/ISO précise quoique ce soit à ce sujet ? Dois-je
remonter un rapport de bogue aux équipes gcc ?

D'avance merci,

Guillaume

4 réponses

Avatar
Eric Levenez
Le 26/01/09 20:50, dans <497e1422$0$21820$, « none »
<""seventh"@none">> a écrit :

Récemment, j'ai été confronté au problème suivant (architecture 64bits).
Soit le type Type :

typedef struct { int a; void * b } Type;

Sans optimisation, on a généralement sizeof(Type) = 16. Il y a 4 octets
d'alignement entre 'a' et 'b'.

J'avais pris l'habitude de systématiquement initialiser mes instance de
Type par un bzero() bien senti. Je pouvais ainsi les comparer à coup de
memcmp, puisque les octets d'alignement étaient a priori toujours à 0.



"À priori" il est très dangereux de croire qu'un champ caché de padding aura
toujours une valeur donnée, ni même toujours la même valeur.

Cependant, je me suis rendu compte récemment que les versions récentes
de gcc (4.1.2 et 4.3.2) empilaient les structures champ par champ plutôt
que l'intégralité des instances lors du passage d'argument par valeur.
Il se peut donc que dans la fonction appelée, les octets d'alignement de
l'instance une fois dépilée ne soient pas à 0.



Cela dépend aussi sûrement des CPU, et pas uniquement du compilateur.

Est-ce que la norme C/ISO précise quoique ce soit à ce sujet ? Dois-je
remonter un rapport de bogue aux équipes gcc ?



La norme dit qu'il ne faut pas faire des "à priori". En §6.2.6.1, il est
noté "any padding bytes take unspecified values", et il est aussi noté que
l'usage de memcmp ne doit PAS être utilisé quand il y a du padding
(exactement ce que tu fais, quoi).

--
Éric Lévénez
FAQ de fclc : <http://www.levenez.com/lang/c/faq/>
Avatar
-ed-
On 26 jan, 20:50, none <""seventh"@(none)"> wrote:

Est-ce que la norme C/ISO précise quoique ce soit à ce sujet ? Dois-j e
remonter un rapport de bogue aux équipes gcc ?



Il n'y a pas de bug et le comportement est conforme à la norme. Les
mauvaises pratiques finissent par nous péter à la g. C'est normal...
(n'est-ce pas Mr Maddock !)
Avatar
none
-ed- a écrit :
On 26 jan, 20:50, none <""seventh"@(none)"> wrote:

Est-ce que la norme C/ISO précise quoique ce soit à ce sujet ? Dois-je
remonter un rapport de bogue aux équipes gcc ?



Il n'y a pas de bug et le comportement est conforme à la norme. Les
mauvaises pratiques finissent par nous péter à la g. C'est normal...
(n'est-ce pas Mr Maddock !)




Merci pour vos réponses à tous les deux, je vais pouvoir émettre un
rapport de bogue (vous ne croyiez tout de même pas que c'était *mon* code ?)

Guillaume
Avatar
Charlie Gordon
"none" <""seventh"@(none)"> a écrit dans le message de news:
497f5308$0$5255$
-ed- a écrit :
On 26 jan, 20:50, none <""seventh"@(none)"> wrote:

Est-ce que la norme C/ISO précise quoique ce soit à ce sujet ? Dois-je
remonter un rapport de bogue aux équipes gcc ?



Il n'y a pas de bug et le comportement est conforme à la norme. Les
mauvaises pratiques finissent par nous péter à la g. C'est normal...
(n'est-ce pas Mr Maddock !)




Merci pour vos réponses à tous les deux, je vais pouvoir émettre un
rapport de bogue (vous ne croyiez tout de même pas que c'était *mon* code
?)



Si j'ai bien compris, il n'y a pas de bug, le comportement est conforme à la
norme, donc tu va remonter le code qui se repose sur la constance du padding
comme étant buggy...
Il y a un moyen simple de corriger le probleme : il suffit de nommer le
padding pour que celui-ci soit preservé par le compilateur lors du passage
des structures en parametre.

par exemple si les int font 32 et les void* 64, utilise cette definition de
Type :

typedef struct { int a; int __pad; void * b } Type;

crade, pas générique, mais corrige le probleme.

--
Chqrlie.