Domanda

Ho qualcosa di simile a questo nel mio codice:

#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;
}

Mi aspetto questo per dare questa uscita:

ble: 1
ble: 2

E lo fa, quando compilato sotto GCC (3.4.5 credo).

La compilazione e l'esecuzione di questo in Visual Studio 2008 tuttavia, conferisce a questo:

ble: 2
ble: 2

La cosa interessante, è che se io do le struct nomi Base-derivato (struct s1 : public Base), funziona correttamente.

Quale comportamento, se esiste, è corretto? È VS solo di essere lezioso, o è conforme allo standard? Mi sto perdendo qualcosa di vitale qui?

È stato utile?

Soluzione

E 'visibile come MSVC è sempre sbagliato dai simboli di debug. Esso genera i nomi temporanei per i struct anonimi, rispettivamente Child::<unnamed-type-First> e Child::<unnamed-type-Second>. V'è tuttavia solo una vtable, prende il nome Child::<unnamed-tag>::'vftable' ed entrambi i costruttori usarlo. Il nome diverso per la vtable è sicuramente parte del bug.

Ci sono diversi bug segnalati in connection.microsoft.com che sono legati a tipi anonimi, nessuno dei quali mai reso allo status di "must-fix". Non quello che si trova, però, AFAICT. Forse la soluzione è troppo semplice.

Altri suggerimenti

Sembra questo un bug in VS 2008, forse perché sovrascrive o ignora il vtable per la prima classe senza nome a favore del vtable per la seconda poiché i nomi interni sono identici. (Quando è il nome uno in modo esplicito, i nomi interni per i VTables non sono più identici.)

Per quanto posso dire dalla norma, questo dovrebbe funzionare come ci si aspetta e gcc è giusto.

Posso confermare che questo è un bug noto nel compilatore VC (e pronti contro termine in VC10); le due classi anonime vengono erroneamente condividono un vtable.

struct

anonime sono non parte dello standard C ++.

Modifica : le strutture anonime sono specie di un termine ambiguo. Può significare due cose:

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

    struct {
        int c;
    };     // 2

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

1 è quello che sta succedendo qui, un nome migliore di struct anonimo sarebbe "struct senza nome". Il tipo struct sé non ha un nome, ma l'oggetto fa (m_A).

2 è anche conosciuto come uno struct anonimo, e non è legale C ++. Non v'è alcun nome di oggetto, e l'idea è che si potrebbe accedere al campo 'c' direttamente su oggetti di tipo esterno. Questo compila solo a causa di un'estensione del compilatore in Visual Studio (fallirà sotto / Za)

3 sindacati anonimi, al contrario, sono legali C ++.

ho confuso i due, perché qui stiamo chiamando # 1 un "struct anonimo", ei fili nel mio cervello incrociata con # 2.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top