9 votes

GCC crée-t-il des typedefs pour les tableaux passés aux fonctions ?

En déboguant du code C avec gdb, je suis tombé sur quelque chose que je n'ai jamais vu ni entendu auparavant ! Le compilateur (gcc -O0) semble avoir créé un nouveau type pour passer un tableau de vecteurs à une fonction... Je pense ! Jetez un coup d'oeil au code et aux informations de gdb ci-dessous :

/* The Vector type - nothing unusual */
typedef struct {
    float x,y,z;
} Vector;

/* The function I was debugging.
 * The second parameter is what seems to have changed */
extern void gui_shader_draw(
    guiShader *shader,
    Vector quad[ 4 ], // << This is the one!
    Vector origin,
    Vector rotation,
    Vector scale,
    bool focus,
    int mode );

J'ai placé un point d'arrêt dans la fonction gui_shader_draw et voici ce que je vois :

break shader.c:248
Breakpoint 1 at 0x80013ac0: file src/gui/shader.c, line 248.
(gdb) continue
Continuing.
// I have split the next line
Breakpoint 1, gui_shader_draw (
    shader=0x80588ea8,
    quad_t=0x80585fe8, // << What the?
    origin=...,
    rotation=...,
    scale=...,
    focus=false,
    mode=3) at src/gui/shader.c:249

// The values quad_t points to are all good
(gdb) print quad_t[0]
$10 = {x = -320, y = -240, z = 0}
(gdb) print quad_t[1]
$11 = {x = 320, y = -240, z = 0}
(gdb) print quad_t[2]
$12 = {x = 320, y = 240, z = 0}
(gdb) print quad_t[3]
$13 = {x = -320, y = 240, z = 0}

D'où vient le quad_t ? Ce n'est certainement pas un typedef dans mon code. L'en-tête système sys/types.h a un alias quad_t (long int) mais cela ne semble pas du tout lié ! Que se passe-t-il ? Ai-je manqué quelque chose d'évident ?

EDIT 1 : Je dois préciser que le code se compile et fonctionne bien. Il n'y a pas de conflit avec une autre variable ou un autre type appelé quad_t. Je suis simplement curieux de savoir ce que GCC a fait et pourquoi.

EDIT 2 : Comme suggéré, j'ai jeté un coup d'oeil à la sortie du préprocesseur et en effet toutes les instances de 'Vector quad[4]' ont été changées en 'Vector quad_t[4]', donc le nom a changé, pas le type.

extern void gui_shader_draw(
    guiShader *shader,
    Vector quad_t[ 4 ],
    Vector origin,
    Vector rotation,
    Vector scale,
    _Bool focus,
    int mode
 );

Il n'y a pas de typedefs appelés 'quad_t' dans la sortie du préprocesseur. Mais j'ai trouvé ceci dans sys/types.h (que j'ai manqué auparavant - d'oh !)

/usr/include$ find . | xargs grep -s quad_t
./sys/types.h:typedef    __uint64_t      u_quad_t;
./sys/types.h:typedef    __int64_t       quad_t;
./sys/types.h:typedef    quad_t *        qaddr_t;
./sys/types.h:#  define  quad            quad_t // << There you are!

4voto

AndreyT Points 139512

Ce qui se passe dans votre code n'a absolument rien à voir avec les typedefs, puisque le changement n'est en aucun cas lié aux types. Ce qui a changé est le nom du paramètre de la fonction et non de son type, ce qui est immédiatement évident dans la sortie de votre débogueur.

Puisque vous voyez ce changement dans la sortie du préprocesseur, la seule explication raisonnable est que quelque part dans le code il y a un fichier

#define quad quad_t

Vous devez donc chercher #define pour quad pas pour quad_t . Inutile de dire que #define ne sera pas présent dans la sortie du préprocesseur. Vous devez effectuer une recherche globale dans tous les fichiers d'en-tête inclus (directement et indirectement).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X