Sizeof (enum) può differire da sizeof (std :: Sottostante_tipo <Enum> :: tipo)?


16

Recentemente è venuto fuori in una revisione del codice che nel seguente esempio:

enum class A : uint8_t
{
    VAL1, VAL2 
};

...
std::vector<A> vOfA; // Assume this is sized and full of some stuff.
std::memcpy(wire_buffer, vOfA.data(), vOfA.size() * sizeof(A));

Dovremmo usare sizeof(std::underlying_type<A>::type)invece di sizeof(A). È possibile che questi possano mai differire? Qualcuno ha un preventivo standard che lo garantisce?


Collegare qual è la dimensione dei dati di un tipo enum in C ++? (che dovrebbe essere fatto per coprire anche quelli con ambito :-).
Ghianda

3
Anche se hanno le stesse dimensioni (il che è più che probabile il caso), qual è l'argomento contro l'utilizzo sizeof(A)? Inoltre: se hanno dimensioni diverse (improbabile), l'utilizzo sizeof(std::underlying_type<A>)sarebbe semplicemente sbagliato.
Sander De Dycker,

1
sizeof(std::underlying_type<A>)è probabilmente 1. Volevi dire ::type?
LF

1
@SanderDeDycker Sì, quando si ha a che fare con As, si vuole sicuramente usare sizeof(A)e al codice non dovrebbe importare che tipo di tipo Asia.
Ghianda

@LF Sì, errore di battitura. Il titolo lo aveva corretto.
Fantastico Mr Fox,

Risposte:


12

In C ++ 03 era garantito (beh, comunque per le enumerazioni senza ambito).

[dcl.enum] Dichiarazioni di enumerazione (sottolineatura mia)

6 Il tipo sottostante di un'enumerazione è un tipo integrale che può rappresentare tutti i valori dell'enumeratore definiti nell'enumerazione. Se nessun tipo integrale può rappresentare tutti i valori dell'enumeratore, l'enumerazione non è corretta. È definito dall'implementazione quale tipo integrale viene utilizzato come tipo sottostante per un'enumerazione, tranne per il fatto che il tipo sottostante non deve essere maggiore di int a meno che il valore di un enumeratore non possa rientrare in un int o in un unsigned int. Se l'elenco di enumeratori è vuoto, il tipo sottostante è come se l'enumerazione avesse un singolo enumeratore con valore 0. Il valore di sizeof()applicato a un tipo di enumerazione, un oggetto di tipo di enumerazione o un enumeratore, è il valore di sizeof()applicato all'oggetto tipo sottostante .

Poi è arrivato n2347 , il documento che è stato adottato per le enumerazioni fortemente tipizzate ( enum class) e altri miglioramenti alle enumerazioni senza ambito, e la frase in grassetto è stata rimossa. È interessante notare che una versione precedente della proposta, n2213 , aveva una sostituzione per la frase rimossa. Ma non è stato inserito nella versione adottata.

Quindi, nel moderno C ++, non vi è alcun obbligo che le dimensioni siano uguali. Sebbene da un punto di vista pratico, è improbabile che le implementazioni abbiano modificato il comportamento prescritto da C ++ 03 per le dimensioni di enumerazione.

Si potrebbe ritenerlo un difetto nello standard.


2
Come è stato garantito qualcosa in C ++ 03 per una funzionalità che non esisteva nella lingua? oO
Razze di leggerezza in orbita

4
@LightnessRaceswithMonica - L'idea di un tipo sottostante non è nuova. È solo che C ++ 11 ti ha permesso di specificarlo tu stesso.
StoryTeller - Unslander Monica

Lo so. La nozione di enum con ambito ( enum class) è nuova.
Razze di leggerezza in orbita

@LightnessRaceswithMonica - Penso che si possa potenzialmente criticare la proposta qui. Ha fatto due cose, ha introdotto le enumerazioni con ambito e ha permesso a tutte le enumerazioni (non solo a quelle con ambito) di avere il set di tipi sottostante. Da qui il "garantito" in C ++ 03.
StoryTeller - Unslander Monica

1
@ StoryTeller-UnslanderMonica Sì, la domanda è la stessa che penso, portata o meno.
Fantastico Mr Fox,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.