64 votes

Comment compiler du code C avec des structures / unions anonymes?

Je peux le faire en c ++ / g ++:

 struct vec3 { 
    union {
        struct {
            float x, y, z;
        }; 
        float xyz[3];
    }; 
};
 

Ensuite,

 vec3 v;
assert(&v.xyz[0] == &v.x);
assert(&v.xyz[1] == &v.y);
assert(&v.xyz[2] == &v.z);
 

marchera.

Comment fait-on cela en c avec gcc? j'ai

 typedef struct {
    union {
        struct {
            float x, y, z;
        };
        float xyz[3];
    };
} Vector3;
 

Mais je reçois des erreurs tout autour, en particulier

 line 5: warning: declaration does not declare anything
line 7: warning: declaration does not declare anything
 

50voto

user287561 Points 376

selon http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields

-fms-extensions activera la fonctionnalité que vous (et moi) voulons.

32voto

R Samuel Klatchko Points 44549

C n'a pas de structures ou de syndicats anonymes. Vous devez les nommer:

 typedef struct {
    union {
        struct {
            float x, y, z;
        } individual;
        float xyz[3];
    } data;
} Vector3;
 

Et puis, vous devez utiliser le nom pour y accéder:

 assert(&v.data.xyz[0] == &v.data.individual.x);
 

Dans ce cas, comme votre structure de niveau supérieur comporte un seul élément de type union, vous pouvez simplifier ceci:

 typedef union {
    struct {
        float x, y, z;
    } individual;
    float xyz[3];
} Vector3;
 

et accéder aux données devient maintenant:

 assert(&v.xyz[0] == &v.individual.x);
 

25voto

hdante Points 2192

La nouvelle norme C11 anonyme des structures et des syndicats, voir avant-propos le paragraphe 6 de l'avril 2011 projet de.

http://en.wikipedia.org/wiki/C1X

La partie étrange, c'est que gcc et clang maintenant anonyme des structures et des syndicats en C89 et C99 mode. Dans ma machine, pas de mises en garde apparaissent.

11voto

Ionoclast Brigham Points 194

On peut aussi toujours faire ce qui suit:

typedef struct
{
    float xyz[0];
    float x, y, z;
}Vec3;

La longueur nulle de la matrice de ne pas allouer de stockage, et dit juste C de "point à ce que la prochaine chose est déclaré." Ensuite, vous pouvez y accéder comme tout autre tableau:

int main(int argc, char** argv)
{
    Vec3 tVec;
    for(int i = 0; i < 3; ++i)
    {
        tVec.xyz[i] = (float)i;
    }

    printf("vec.x == %f\n", tVec.x);
    printf("vec.y == %f\n", tVec.y);
    printf("vec.z == %f\n", tVec.z);

    return 0;
}

Résultat:

vec.x == 0.000000
vec.y == 1.000000
vec.z == 2.000000

Si vous voulez être très paranoïaque, vous pouvez spécifier manuellement les données d'emballage stratégie en fonction de votre plate-forme.

8voto

AndreyT Points 139512

Anonyme syndicats est une fonctionnalité du langage C++. Le langage C n'a pas anonyme syndicats.

Anonyme les structures n'existent pas dans ni C ni C++.

La déclaration que vous avez présentés dans votre question peut compiler avec GCC C++ compilateur, mais il serait juste d'un compilateur spécifique de l'extension, qui n'a rien à voir avec ni standard C ni C++standard.

En plus de cela, peu importe comment la mettre en œuvre, ni C ni C++ langage garantit que vos affirmations.

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