Question

J'ai quelque chose de semblable à cela dans mon code:

#include <iostream>
#include <cstdlib>

struct Base
{
  virtual int Virtual() = 0;
};

struct Child
{
  struct : public Base
  {
    virtual int Virtual() { return 1; }
  } First;

  struct : public Base
  {
    virtual int Virtual() { return 2; }
  } Second;
};

int main()
{
  Child child;
  printf("ble: %i\n", ((Base*)&child.First)->Virtual());
  printf("ble: %i\n", ((Base*)&child.Second)->Virtual());

  system("PAUSE");
  return 0;
}

Je pense que cela donne cette sortie:

ble: 1
ble: 2

et il le fait, lorsqu'il est compilé sous GCC (3.4.5 je crois).

Compiler et l'exécution de ce sous Visual Studio 2008 cependant, donne ceci:

ble: 2
ble: 2

Ce qui est intéressant, est que si je donne les noms des structs dérivés de base (struct s1 : public Base), il fonctionne correctement.

Quel comportement, le cas échéant, est correct? Est-VS juste être bégueule, ou est-il conforme à la norme? Suis-je manque quelque chose de vital ici?

Était-ce utile?

La solution

Il est visible comment MSVC devient mal à partir des symboles de débogage. Il génère des noms temporaires pour les structs anonymes, respectivement Child::<unnamed-type-First> et Child::<unnamed-type-Second>. Il n'y a cependant qu'un seul vtable, il est nommé Child::<unnamed-tag>::'vftable' et les deux constructeurs utilisent. Le nom différent pour la vtable est certainement partie du bogue.

Il y a plusieurs bugs signalés à connection.microsoft.com qui sont liés à des types anonymes, dont aucun jamais fait à l'état « doit-fix ». Pas celui que vous avez trouvé que, AFAICT. Peut-être la solution de contournement est trop simple.

Autres conseils

Il semble que ce bogue dans VS 2008, peut-être parce qu'il ne tient pas compte du ou écrase vtable pour la première classe sans nom en faveur de la vtable pour la deuxième étant donné que les noms internes sont identiques. (Lorsque vous nommez un explicitement, les noms internes pour les vtables ne sont plus identiques.)

Pour autant que je peux dire de la norme, cela devrait fonctionner comme prévu et gcc est juste.

Je peux confirmer ceci est un bogue connu dans le compilateur VC (et prises en pension à VC10); les deux classes anonymes partagent de façon incorrecte un vtable.

structs anonymes sont pas partie de la norme C ++.

Modifier : struct anonymes sont genre d'un terme ambigu. Cela peut vouloir dire deux choses:

class outer
{
public:
    struct {
        int a;
        int b;
    } m_a; // 1

    struct {
        int c;
    };     // 2

    union {
        int d;
        int e;
    };     // 3
};

1 est ce qui se passe ici, un meilleur nom que struct anonyme serait « struct sans nom ». Le type struct lui-même n'a pas de nom, mais l'objet ne (m_a).

2 est également connu comme un struct anonyme, et est pas légal C ++. Il n'y a pas de nom de l'objet, et l'idée est que vous pouvez accéder à « c » le champ directement sur les objets de type extérieur. Cela compile seulement en raison d'une extension du compilateur dans Visual Studio (échouera sous / Za)

3 syndicats anonymes, en revanche, sont légaux C ++.

Je confondu les deux, parce qu'ici nous appelons # 1 un « struct anonyme », et les fils dans mon cerveau avec traversais # 2.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top