105 votes

Pourquoi le C ++ n'autorise-t-il pas les structures et les unions anonymes?

Certains compilateurs C++ permis anonyme syndicats et les structures comme une extension de C++ standard. C'est un peu de sucre syntaxique qui est parfois très utile.

Quelle est la justification qui empêche d'être partie de la norme? Est-il une technique de barrage? Philosophique? Ou tout simplement ne suffit pas d'un besoin de la justifier?

Voici un exemple de ce dont je parle:

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

Mon compilateur va l'accepter, mais il avertit que "nameless struct/union" est un non-extension standard du C++.

59voto

bames53 Points 38303

Comme d'autres l'ont souligné anonyme syndicats sont autorisés dans la norme C++, mais anonymes, les structures ne sont pas.

La raison pour cela est que C prend en charge anonyme syndicats, mais pas anonyme, les structures*, C++ prend en charge l'ancien, pour la compatibilité, mais pas le dernier parce qu'il n'est pas nécessaire pour la compatibilité.

En outre, il n'y a pas beaucoup d'utilisation anonyme des structures en C++. L'utilisation de vous démontrer, à avoir une structure contenant trois chars qui peuvent être visés, soit par .v[i]ou .x, .y, et .z, je crois entraîne un comportement non défini en C++. C++ ne vous autorise pas à écrire à un membre d'un syndicat, dire .v[1], puis de les lire à partir d'un autre membre, dire .y. Bien que le code qui fait ce n'est pas rare, il n'est pas bien définie.

C++installations pour les types définis par l'utilisateur fournir des solutions de rechange. 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 apparemment ajoute anonyme des structures, donc d'une future révision de C++ peut les ajouter.

25voto

bobobobo Points 17477

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

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

Bien sûr, anonyme structures a été un MSVC extension. Mais l'ISO C11 autorise maintenant, et gcc permet, et n'a donc Apple llvm compilateur.

Pourquoi en C11 et pas du C++11? Je ne suis pas sûr, mais dans la pratique la plupart (gcc++, MSVC++ et Apple compilateur C++) compilateurs C++ soutenir.

4voto

Dan Points 3171

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

Une union de la forme

 union { member-specification } ;
 

s'appelle un syndicat anonyme; il définit un objet non nommé de type non nommé.

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 définitions de macro méchant.

1voto

David Thornley Points 39051

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

À quoi sert une structure ou une classe anonyme comme remplissant? Avant de spéculer sur la raison pour laquelle quelque chose ne figure pas dans la norme, j'aimerais en avoir une idée, et je ne vois pas l'utilité d'une structure anonyme.

0voto

KennyTM Points 232647

Votre code

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

c'est comme

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

ce qui est sûrement non valide (en C99 et avant).

La raison en est probablement pour simplifier l'analyse (en C), parce que dans ce cas, vous avez uniquement besoin de vérifier que l'struct/union corps n'a qu'à "déclaration de déclarations" comme

Type field;

Cela dit, gcc et "d'autres compilateurs" soutient sans nom des champs comme une extension.

Edit: Anonyme les structures sont maintenant officiellement pris en charge en C11 (§6.7.2.1/13).

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