Bisakah sizeof (enum) berbeda dari sizeof (std :: underlying_type <Enum> :: type)?

16

Baru-baru ini muncul ulasan kode yang dalam contoh berikut:

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));

Kita seharusnya menggunakan sizeof(std::underlying_type<A>::type)bukan sizeof(A). Mungkinkah ini berbeda? Apakah seseorang memiliki kutipan standar yang menjamin ini?

Tuan Fox yang luar biasa
sumber
Menautkan berapa ukuran data tipe enum di C ++? (yang harus dibuat untuk menutupi yang tercakup juga :-).
Acorn
3
Sekalipun ukurannya sama (yang kemungkinan besar terjadi), apa argumen yang menentang penggunaannya sizeof(A)? Juga: jika mereka berbeda ukuran (tidak mungkin), menggunakan sizeof(std::underlying_type<A>)akan menjadi salah.
Sander De Dycker
1
sizeof(std::underlying_type<A>)mungkin 1. Apakah maksud Anda ::type?
LF
1
@ SanderDeDycker Ya, ketika berhadapan dengan As, orang pasti ingin menggunakan sizeof(A)dan kodenya seharusnya tidak peduli apa jenisnya A.
Acorn
@ LF Yap, salah ketik. Judulnya sudah benar.
Fantastic Mr Fox

Jawaban:

12

Dalam C ++ 03 dijamin (well, untuk enumerasi yang tidak teropong toh).

[dcl.enum] Deklarasi enumerasi (penekanan pada tambang)

6 Jenis enumerasi yang mendasari adalah tipe integral yang dapat mewakili semua nilai enumerator yang ditentukan dalam enumerasi. Jika tidak ada tipe integral yang bisa mewakili semua nilai enumerator, enumerasi itu salah bentuk. Ini adalah implementasi-didefinisikan tipe integral mana yang digunakan sebagai tipe yang mendasari untuk enumerasi kecuali bahwa tipe yang mendasari tidak boleh lebih besar dari int kecuali nilai enumerator tidak dapat ditampung dalam int atau int unsigned. Jika daftar enumerator kosong, tipe yang mendasarinya adalah seolah-olah enumerasi memiliki enumerator tunggal dengan nilai 0. Nilai yang sizeof()diterapkan pada tipe enumerasi, objek tipe enumerasi, atau enumerator, adalah nilai yang sizeof()diterapkan pada tipe yang mendasarinya .

Kemudian datang n2347 , makalah yang diadopsi untuk enumerasi yang sangat diketik ( enum class) dan peningkatan lainnya untuk enumerasi yang tidak dicopot, dan kalimat tersebut dicetak tebal. Cukup menarik, versi proposal sebelumnya, n2213 , memiliki pengganti untuk kalimat yang dihapus. Tapi itu tidak masuk ke versi yang diadopsi.

Jadi di C ++ modern, tidak ada kewajiban untuk ukurannya sama. Meskipun dari sudut pandang praktis, implementasi tidak mungkin telah mengubah perilaku yang ditentukan oleh C ++ 03 untuk ukuran enumerasi.

Orang bisa menganggapnya sebagai cacat dalam standar.

StoryTeller - Unslander Monica
sumber
2
Bagaimana sesuatu bisa dijamin di C ++ 03 untuk fitur yang tidak ada dalam bahasa? oO
Lightness Races in Orbit
4
@LightnessRaceswithMonica - Gagasan tentang tipe yang mendasarinya bukanlah hal baru. Hanya saja C ++ 11 memungkinkan Anda menentukannya sendiri.
StoryTeller - Unslander Monica
Saya tahu itu. Gagasan scoped enum ( enum class) adalah baru.
Lightness Races in Orbit
@LightnessRaceswithMonica - Saya pikir seseorang berpotensi salah proposal di sini. Ia melakukan dua hal, memperkenalkan pencacahan scoped dan memungkinkan semua pencacahan (tidak hanya pencakupan) untuk memiliki tipe set yang mendasarinya. Karenanya "dijamin" dalam C ++ 03.
StoryTeller - Unslander Monica
1
@ StoryTeller-UnslanderMonica Ya, pertanyaannya sama, saya pikir, scoped atau unscoped.
Fantastic Mr Fox