2015-08-04 30 views
5

Mi stavo chiedendo ... Diciamo che ho una struttura POD in C++. Se inserissi uno static_assert lì dentro, rovinerebbe il fatto che sia un POD?Un static_assert in un POD rovinerà il POD?

So che posso facilmente mettere da qualche altra parte, sto solo chiedendo perché mi interessa se devo o non devo fare questo ...

In altre parole (più specifici):

#include <iostream> 
#include <type_traits> 

struct A 
{ 
    void* ptr; 

    static_assert(sizeof(void*) == 8, "Pointer should have size 8; platform unsupported"); 
}; 

int main() 
{ 
    // Is it guaranteed that this will evaluate to 'true'? 
    std::cout << std::is_pod<A>::value << std::endl; 
} 
+7

Non credo, 'static_assert' prende il via in fase di compilazione, non credo che sia anche incorporato nel binario risultante .. Non ho lo standard accanto a me per ottenere una risposta accurata –

+0

Immagino' std :: is_pod' non può davvero essere sbagliato. – Quentin

+0

@DavidHaim Certo, questo è il punto di 'static_assert'. Ancora non è definito come implementarlo - quindi se generasse un membro virtuale per fare il suo lavoro, potrebbe teoricamente rovinare il 'is_pod'. (Non che io capissi perché lo farebbe, ma questa è un'altra storia ...) Giusto? – atlaste

risposta

4

In C++ 11 un tipo è considerato POD se è

  • trivial (un tipo scalare, una classe banalmente copiabile con un costruttore di default banale, o matrice di tale tipo/classe)
  • standard layout (non ha funzioni virtuali, classi base virtuali, ecc)

fondo niente suscettibile di impedire la copia oggetti come se fossero semplicemente costituiti da byte grezzi.

static_assert s sono lì per convalidare qualcosa in fase di compilazione e non modifica il layout dell'oggetto o la banalità (o la sua mancanza) nella costruzione, copia, ecc. Di un oggetto. Quindi l'aggiunta di un numero qualsiasi di asserzioni statiche a un tipo (struct/class) non dovrebbe modificare il POD-ness di esso.

È possibile verificare se il compilatore sta considerando un tipo come POD utilizzando std::is_pod<T>::value. Questo non cambierebbe prima e dopo aver aggiunto static_assert s ad esso.

Questo è tutto ciò che dice lo standard relativo a static_assert s. Da [dcl.dcl]:

In un static_assert dichiarazione il espressione-costante è un'espressione costante che può essere convertito in contestualmente bool. Se il valore dell'espressione quando convertito è vero, la dichiarazione non ha alcun effetto. In caso contrario, il programma è mal formato e il messaggio diagnostico risultante (1.4) includerà il testo della stringa letterale, tranne per il fatto che non è necessario che i caratteri nel set di caratteri di origine (2.3) compaiano nel messaggio di diagnostica.

+0

Certo, entrambi vengono valutati anche in fase di compilazione, ma nessuno dei due ha un vincolo di implementazione nello std che impedisce loro di aggiungere una funzione virtuale, violando così i vincoli POD, giusto? – atlaste

+1

La parte banale ha il vincolo che la classe non dovrebbe avere alcuna funzione virtuale. Se non è banale, non è un POD. – legends2k

+3

@atlaste: Non ricordo un ban esplicito (che richiederebbe il controllo dell'intero standard), ma credo che ci sia un ampio consenso sul fatto che i compilatori non possano aggiungere funzioni virtuali solo perché ne hanno voglia. L'unico modo per aggiungere una funzione virtuale secondo lo standard è dichiararne uno o ereditarne uno. (IOW, il consenso è che questa è una lista esaustiva) – MSalters