Tôi đã sử dụng công đoàn sớm hơn một cách thoải mái; hôm nay tôi đã hoảng hốt khi đọc bài đăng này và biết rằng mã này
union ARGB
{
uint32_t colour;
struct componentsTag
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} components;
} pixel;
pixel.colour = 0xff040201; // ARGB::colour is the active member from now on
// somewhere down the line, without any edit to pixel
if(pixel.components.a) // accessing the non-active member ARGB::components
thực sự là hành vi không xác định Tôi đang đọc từ một thành viên của hiệp hội khác với hành vi được viết gần đây để dẫn đến hành vi không xác định. Nếu đây không phải là mục đích sử dụng của công đoàn, thì đó là gì? Ai đó có thể vui lòng giải thích nó công phu?
Cập nhật:
Tôi muốn làm rõ một vài điều trong nhận thức muộn màng.
- Câu trả lời cho câu hỏi không giống với C và C ++; đứa trẻ không biết gì của tôi đã gắn thẻ nó là cả C và C ++.
- Sau khi quét qua tiêu chuẩn của C ++ 11, tôi không thể kết luận rằng nó gọi truy cập / kiểm tra một thành viên công đoàn không hoạt động là không xác định / không xác định / xác định thực hiện. Tất cả những gì tôi có thể tìm thấy là §9,5 / 1:
Nếu một liên kết bố cục tiêu chuẩn chứa một số cấu trúc bố cục tiêu chuẩn có chung một chuỗi ban đầu chung và nếu một đối tượng của loại kết hợp bố cục tiêu chuẩn này chứa một trong các cấu trúc bố cục tiêu chuẩn, thì được phép kiểm tra trình tự ban đầu chung của bất kỳ của các thành viên cấu trúc tiêu chuẩn bố trí. §9.2 / 19: Hai cấu trúc bố cục tiêu chuẩn chia sẻ một chuỗi ban đầu chung nếu các thành viên tương ứng có các loại tương thích bố cục và không thành viên nào là trường bit hoặc cả hai đều là trường bit có cùng độ rộng cho một hoặc nhiều chuỗi ban đầu các thành viên.
- Trong khi ở C, ( C99 TC3 - DR 283 trở đi), việc làm như vậy là hợp pháp ( cảm ơn Pascal Cuoq vì đã đưa ra điều này). Tuy nhiên, cố gắng thực hiện nó vẫn có thể dẫn đến hành vi không xác định , nếu giá trị đọc xảy ra không hợp lệ (được gọi là "biểu diễn bẫy") cho loại được đọc qua. Mặt khác, giá trị đọc được thực hiện được xác định.
C89 / 90 gọi điều này theo hành vi không xác định (Phụ lục J) và cuốn sách của K & R nói rằng việc triển khai được xác định. Trích dẫn từ K & R:
Đây là mục đích của một liên minh - một biến duy nhất có thể nắm giữ một cách hợp pháp bất kỳ một trong một số loại. [...] Miễn là việc sử dụng phù hợp: loại được truy xuất phải là loại được lưu trữ gần đây nhất. Trách nhiệm của người lập trình là theo dõi loại nào hiện đang được lưu trữ trong một liên minh; kết quả phụ thuộc vào việc thực hiện nếu một cái gì đó được lưu trữ dưới dạng một loại và được trích xuất dưới dạng khác.
Trích xuất từ TC ++ PL của Stroustrup (nhấn mạnh của tôi)
Việc sử dụng các công đoàn có thể cần thiết cho sự tương thích của dữ liệu [...] đôi khi bị sử dụng sai cho "chuyển đổi loại ".
Trên hết, câu hỏi này (có tiêu đề vẫn không thay đổi kể từ câu hỏi của tôi) được đặt ra với mục đích tìm hiểu mục đích của các công đoàn VÀ không dựa trên những gì tiêu chuẩn cho phép Eg Sử dụng quyền thừa kế để sử dụng lại mã, tất nhiên, được cho phép bởi tiêu chuẩn C ++, nhưng đó không phải là mục đích hay mục đích ban đầu của việc giới thiệu tính kế thừa như một tính năng ngôn ngữ C ++ . Đây là lý do câu trả lời của Andrey tiếp tục vẫn là câu trả lời được chấp nhận.
scouring C++11's standard I couldn't conclusively say that it calls out accessing/inspecting a non-active union member is undefined [...] All I could find was §9.5/1
...có thật không? bạn trích dẫn một ghi chú ngoại lệ , không phải là điểm chính ngay đầu đoạn : "Trong một liên minh, nhiều nhất một trong số các thành viên dữ liệu không tĩnh có thể hoạt động bất cứ lúc nào, nghĩa là giá trị của nhiều nhất một các thành viên dữ liệu không tĩnh có thể được lưu trữ trong một liên minh bất cứ lúc nào. " - và xuống p4: "Nói chung, người ta phải sử dụng các lệnh gọi hàm hủy rõ ràng và các toán tử vị trí mới để thay đổi thành viên tích cực của liên minh "
b, g, r,
vàa
có thể không liền kề nhau, và do đó không khớp với bố cục của auint32_t
. Điều này ngoài các vấn đề Endianess mà những người khác đã chỉ ra.