Pourquoi C ++ n’autorise-t-il pas les structures anonymes?

Certains compilateurs C ++ autorisent les unions anonymes et les structures comme extension du standard C ++. C’est un peu de sucre syntaxique qui est parfois très utile.

Quelle est la justification qui empêche que cela fasse partie de la norme? Y a-t-il un barrage technique? Une philosophie? Ou tout simplement pas besoin de le justifier?

Voici un exemple de ce dont je parle:

struct vector3 { union { struct { float x; float y; float z; }; float v[3]; }; }; 

Mon compilateur l’acceptera, mais il avertit que “struct / union sans nom” est une extension non standard de C ++ .

Comme d’autres l’ont souligné, les unions anonymes sont autorisées en C ++ standard, mais les structures anonymes ne le sont pas.

La raison en est que C prend en charge les unions anonymes mais pas les structures anonymes *, par conséquent C ++ prend en charge la première pour la compatibilité mais pas la seconde car elle n’est pas nécessaire pour la compatibilité.

De plus, les structures anonymes en C ++ ne sont pas très utiles. L’utilisation que vous démontrez, pour avoir une structure contenant trois flottants, soit par .v[i] , soit par .x , .y et .z , aboutit à un comportement indéfini en C ++. C ++ ne vous permet pas d’écrire à un membre d’une union, par exemple .v[1] , puis de lire un autre membre, par exemple .y . Bien que ce code ne soit pas rare, il n’est pas bien défini.

Les fonctionnalités de C ++ pour les types définis par l’utilisateur fournissent des solutions alternatives. Par exemple:

 struct vector3 { float v[3]; float &operator[] (int i) { return v[i]; } float &x() { return v[0]; } float &y() { return v[1]; } float &z() { return v[2]; } }; 

* C11 ajoute apparemment des structures anonymes, donc une future révision de C ++ pourrait les append.

Je vais dire, vous pouvez nettoyer votre déclaration vector3 en utilisant simplement une union

 union vector3 { struct { float x, y, z; } ; float v[3] ; } ; 

Bien sûr, les structures anonymes étaient une extension MSVC . Mais ISO C11 le permet maintenant, et gcc le permet , tout comme le compilateur llvm d’Apple.

Pourquoi en C11 et non en C ++ 11? Je ne suis pas sûr, mais pratiquement tous les compilateurs C ++ (gcc ++, MSVC ++ et compilateur C ++ d’Apple) les supportent.

Pas sûr de ce que vous voulez dire. Section 9.5 de la spécification C ++, article 2:

Une union de la forme

 union { member-specification } ; 

s’appelle une union anonyme; il définit un object sans nom de type sans nom.

Vous pouvez faire des choses comme ça aussi:

 void foo() { typedef struct { // unnamed, is that what you mean by anonymous? int a; char b; } MyStructType; // this is more of a "C" style, but valid C++ nonetheless struct { // an anonymous struct, not even typedef'd double x; double y; } point = { 1.0, 3.4 }; } 

Pas toujours très utile … bien que parfois utile dans les mauvaises définitions de macro.

Les syndicats peuvent être anonymes. voir la norme, 9.5 paragraphe 2.

Dans quel but voyez-vous une structure ou une classe anonyme comme satisfaisante? Avant de spéculer sur la raison pour laquelle quelque chose ne figure pas dans la norme, j’aimerais avoir une idée de ce que cela devrait être, et je ne vois pas d’utilisation d’une structure anonyme.

Sur la base de l’édition, des commentaires et de cet article MSDN: Structures anonymes , je vais risquer de deviner – cela ne correspond pas au concept d’encapsulation. Je ne m’attendrais pas à ce qu’un membre d’une classe joue avec mon espace de noms de classe au-delà du simple ajout d’un membre. De plus, les modifications apscopes à la structure anonyme peuvent affecter ma classe sans autorisation.

Votre code

 union { struct { float x; float y; float z; }; float v[3]; }; 

est comme

 union Foo { int; float v[3]; }; 

qui est sûrement invalide (en C99 et avant).

La raison est probablement de simplifier l’parsing (en C), car dans ce cas, il suffit de vérifier que le corps struct / union n’a que des “déclarations de déclarants” comme

 Type field; 

Cela dit, gcc et “autres compilateurs” prennent en charge les champs sans nom comme extension.

Edit: Les structures anonymes sont désormais officiellement sockets en charge dans C11 (§ 6.7.2.1 / 13).