2011-01-23 15 views
5

Di seguito è riportato un semplice test su ebco, l'ho compilato sia su vc9 che su g ++. Le uscite differiscono su entrambi i compilatori. Quello che voglio sapere è se il comportamento di vc è conforme.ottimizzazione della classe base vuota

#include <iostream> 

class empty 
{ 
}; 

class empty_one : public empty {}; 
class empty_two : public empty {}; 

class non_empty 
    : public empty_one 
    , public empty_two 
{ 
}; 

int main() 
{ 
    std::cout << "sizeof(empty): " << sizeof(empty) << std::endl; 
    std::cout << "sizeof(empty_one): " << sizeof(empty_one) << std::endl; 
    std::cout << "sizeof(empty_two): " << sizeof(empty_two) << std::endl; 
    std::cout << "sizeof(non_empty): " << sizeof(non_empty) << std::endl; 

    std::cout << std::endl; 

    non_empty a[2]; 

    void* pe10 = static_cast<empty*>(static_cast<empty_one*>(&a[0])); 
    void* pe20 = static_cast<empty*>(static_cast<empty_two*>(&a[0])); 
    std::cout << "address of non_empty[0]: " << &a[0] << std::endl; 
    std::cout << "address of empty of empty_one: " << pe10 << std::endl; 
    std::cout << "address of empty of empty_two: " << pe20 << std::endl; 

    std::cout << std::endl; 

    void* pe11 = static_cast<empty*>(static_cast<empty_one*>(&a[1])); 
    void* pe21 = static_cast<empty*>(static_cast<empty_two*>(&a[1])); 
    std::cout << "address of non_empty[1]: " << &a[1] << std::endl; 
    std::cout << "address of empty of empty_one: " << pe11 << std::endl; 
    std::cout << "address of empty of empty_two: " << pe21 << std::endl; 
} 

Su vc,

pe20 == pe11. (test1) 

Può due sotto-oggetti di due oggetti hanno lo stesso indirizzo? È conforme?

Inoltre,

pe20 >= &a[0] + sizeof(a[0]) (test2) 

Può l'indirizzo di un sub-oggetto passa alla fine di un oggetto?

Su g ++, sopra due test non regge.

EDIT: In C++ 0x progetto di norma, 1,8/6,

meno che un oggetto è un campo di bit o una classe base subobject di dimensioni pari a zero, l'indirizzo di tale oggetto è il indirizzo del primo byte che occupa. Due oggetti distinti che non sono né bit-field né sottoggetti classe di base di formato zero hanno indirizzi distinti

Lo standard richiede che due oggetti hanno indirizzo diverso quando sono né bit-field né basi sottoggetti classi di taglia zero. Ma non richiede che due sotto oggetti di dimensioni zero non possano avere lo stesso indirizzo. Quindi test1 può essere vero?

+0

Penso che si possa tranquillamente portarlo al team di MSVC (a meno che non sia già presente). –

risposta

1

pe10 == pe11. Due oggetti secondari di due oggetti hanno lo stesso indirizzo? questo conformant?

No, due oggetti diversi non possono avere lo stesso indirizzo. Se lo hanno, il compilatore non è un reclamo standard.

A proposito, quale versione di VC++ stai usando? Sto usando MSVC++ 2008, e il suo output è questo:

alt text

penso, è significava pe20==pe11? Se è così, allora anche questo è sbagliato, non standard. Il compilatore MSVC++ 2008 ha un bug!

GCC è corretto; vedere l'output da soli: http://www.ideone.com/Cf2Ov


soggetti simili:

When do programmers use Empty Base Optimization (EBO)

+2

Sembra molto rotto, poiché 'pe20' e' pe11' sembrano avere lo stesso indirizzo .... –

+1

Ho appena fatto un refuso nel mio post, dove pe10 in due test dovrebbe essere pe20. WRT il tuo output, ora pe20 == pe11, che non dovrebbe accadere, giusto? – ashen

+1

@Chris: l'ho notato. Così aggiornato il mio post. – Nawaz

1

PE10 == PE11. Due oggetti secondari di due oggetti possono avere lo stesso indirizzo? È conforme?

Nopes!

Dimensione di una classe vuota non può essere zero perché in tal caso due oggetti della stessa classe sarebbe aventi lo stesso indirizzo che non è possibile.

Analogamente due oggetti secondari di due oggetti diversi non possono avere lo stesso indirizzo. Il tuo compilatore non è conforme. Cambiarlo!

+0

Un errore di battitura nel mio post, mi dispiace, l'ho corretto. pe10 dovrebbe essere pe20 ... – ashen

+1

@Alex: ancora non è corretto. Compilatore buggy Buggy. –

Problemi correlati