Sizeof (enum) có thể khác với sizeof (std :: ngầm_type <Enum> :: type) không?


16

Gần đây đã đưa ra một đánh giá mã trong ví dụ sau:

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

Chúng ta nên sử dụng sizeof(std::underlying_type<A>::type)thay vì sizeof(A). Là nó có thể bao giờ khác nhau? Có ai có một trích dẫn tiêu chuẩn đảm bảo điều này?


Liên kết kích thước của dữ liệu loại enum trong C ++ là gì? (cũng nên được thực hiện để bao gồm những người có phạm vi quá :-).
Acorn

3
Ngay cả khi chúng có cùng kích thước (nhiều khả năng là trường hợp), thì đối số chống lại việc sử dụng là sizeof(A)gì? Ngoài ra: nếu chúng có kích thước khác nhau (không chắc), việc sử dụng sizeof(std::underlying_type<A>)sẽ hoàn toàn sai.
Sander De Dycker

1
sizeof(std::underlying_type<A>)có lẽ là 1. Ý bạn là ::typesao
LF

1
@SanderDeDycker Vâng, khi giao dịch với As, người ta chắc chắn muốn sử dụng sizeof(A)và mã không nên quan tâm loại nào là loại A.
Acorn

@LF Yep, lỗi đánh máy. Tiêu đề đã đúng.
Tuyệt vời Mr Fox

Câu trả lời:


12

Trong C ++ 03, nó đã được đảm bảo (dù sao, đối với các liệt kê không được kiểm soát).

[dcl.enum] Khai báo liệt kê (nhấn mạnh của tôi)

6 Kiểu liệt kê cơ bản là một kiểu tích phân có thể biểu thị tất cả các giá trị liệt kê được xác định trong phép liệt kê. Nếu không có loại tích phân nào có thể đại diện cho tất cả các giá trị liệt kê, thì phép liệt kê không được định dạng. Nó được định nghĩa theo kiểu triển khai được sử dụng làm kiểu tích phân được sử dụng làm kiểu liệt kê cho kiểu liệt kê ngoại trừ kiểu cơ sở không được lớn hơn int trừ khi giá trị của một điều tra viên không thể khớp với int hoặc không dấu. Nếu danh sách liệt kê trống, loại bên dưới như thể liệt kê có một liệt kê duy nhất có giá trị 0. Giá trị sizeof()được áp dụng cho loại liệt kê, đối tượng của kiểu liệt kê hoặc liệt kê, là giá trị sizeof()được áp dụng cho loại cơ bản .

Sau đó đến n2347 , bài báo được thông qua cho các kiểu liệt kê được đánh máy mạnh ( enum class) và các cải tiến khác đối với các bảng liệt kê không có giới hạn, và nó đã được in đậm. Thật thú vị, một phiên bản trước đó của đề xuất, n2213 , đã có một sự thay thế cho câu bị loại bỏ. Nhưng nó đã không được đưa vào phiên bản đã được thông qua.

Vì vậy, trong C ++ hiện đại, không có nghĩa vụ nào cho các kích thước giống nhau. Mặc dù từ quan điểm thực tế, việc triển khai dường như không thay đổi hành vi được quy định bởi C ++ 03 đối với kích thước liệt kê.

Người ta có thể coi đó là một khiếm khuyết trong tiêu chuẩn.


2
Làm thế nào một cái gì đó đã được đảm bảo trong C ++ 03 cho một tính năng không tồn tại trong ngôn ngữ? oO
Các cuộc đua nhẹ nhàng trong quỹ đạo

4
@LightnessRaceswithMonica - Khái niệm về một loại cơ bản không phải là mới. Chỉ là C ++ 11 cho phép bạn tự xác định nó.
Người kể chuyện - Unslander Monica

Tôi biết điều đó. Khái niệm enum phạm vi ( enum class) là mới.
Các cuộc đua nhẹ nhàng trong quỹ đạo

@LightnessRaceswithMonica - Tôi nghĩ rằng người ta có thể có khả năng lỗi đề xuất ở đây. Nó đã làm hai việc, giới thiệu bảng liệt kê có phạm vi và cho phép tất cả các kiểu liệt kê (không chỉ các phạm vi có phạm vi) được đặt kiểu cơ bản của chúng. Do đó "được bảo đảm" trong C ++ 03.
Người kể chuyện - Unslander Monica

1
@ StoryTeller-UnslanderMonica Vâng, câu hỏi giống như tôi nghĩ, có phạm vi hoặc không có phạm vi.
Tuyệt vời Mr Fox
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.