Sự nhầm lẫn là C rõ ràng cho phép loại bỏ thông qua một liên minh, trong khi C ++ (c ++ 11) không có sự cho phép như vậy.
c11
6.5.2.3 Cơ cấu và đoàn viên
95) Nếu thành viên được sử dụng để đọc nội dung của đối tượng hợp nhất không giống với thành viên cuối cùng được sử dụng để lưu trữ một giá trị trong đối tượng, phần thích hợp của biểu diễn đối tượng của giá trị được diễn giải lại dưới dạng đại diện đối tượng trong mới loại như được mô tả trong 6.2.6 (một quy trình đôi khi được gọi là '' loại pucky ''). Đây có thể là một đại diện bẫy.
Tình huống với C ++:
c ++ 11
9.5 Liên hiệp [class.union]
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 trong số các thành viên dữ liệu không tĩnh có thể được lưu trữ trong một liên kết bất cứ lúc nào.
C ++ sau này có ngôn ngữ cho phép sử dụng các công đoàn có chứa struct
s với các chuỗi ban đầu phổ biến; tuy nhiên điều này không cho phép loại hình.
Để xác định xem công đoàn type-punning được cho phép trong C ++, chúng ta phải tìm kiếm thêm nữa. Nhớ lại rằngc99 là một tài liệu tham khảo quy phạm cho C ++ 11 (và C99 có ngôn ngữ tương tự như C11 cho phép loại hình liên minh):
3.9 Các loại [basic.types]
4 - Biểu diễn đối tượng của một đối tượng thuộc loại T là chuỗi các đối tượng char không dấu được lấy bởi đối tượng của loại T, trong đó N bằng sizeof (T). Biểu diễn giá trị của một đối tượng là tập hợp các bit chứa giá trị của loại T. Đối với các loại có thể sao chép tầm thường, biểu diễn giá trị là một tập hợp các bit trong biểu diễn đối tượng xác định một giá trị, là một yếu tố riêng biệt của việc triển khai- định nghĩa các giá trị. 42
42) Mục đích là mô hình bộ nhớ của C ++ tương thích với mô hình lập trình ISO / IEC 9899 C.
Nó đặc biệt thú vị khi chúng ta đọc
3.8 Đối tượng trọn đời [basic. Life]
Thời gian tồn tại của một đối tượng loại T bắt đầu khi: - lưu trữ với sự liên kết và kích thước phù hợp cho loại T được lấy và - nếu đối tượng có khởi tạo không tầm thường, việc khởi tạo của nó hoàn tất.
Vì vậy, đối với một kiểu nguyên thủy (mà ipso facto có khởi tạo tầm thường) có trong một liên minh, thời gian tồn tại của đối tượng bao gồm ít nhất là thời gian tồn tại của chính liên minh. Điều này cho phép chúng tôi gọi
3.9.2 Các loại hợp chất [basic.compound]
Nếu một đối tượng của loại T được đặt tại một địa chỉ A, một con trỏ của loại cv T * có giá trị là địa chỉ A được cho là trỏ đến đối tượng đó, bất kể giá trị thu được như thế nào.
Giả sử rằng hoạt động mà chúng ta quan tâm là kiểu xảo quyệt, tức là lấy giá trị của một thành viên công đoàn không hoạt động, và theo như trên, chúng ta có một tham chiếu hợp lệ đến đối tượng được đề cập bởi thành viên đó, hoạt động đó là giá trị chuyển đổi giá trị:
4.1 Chuyển đổi Lvalue-to-rvalue [conv.lval]
Một giá trị của một loại không có chức năng, không phải là mảng T
có thể được chuyển đổi thành một giá trị. Nếu T
là một loại không đầy đủ, một chương trình yêu cầu chuyển đổi này không được định dạng. Nếu đối tượng mà glvalue tham chiếu không phải là đối tượng của loại T
và không phải là đối tượng của loại có nguồn gốc T
hoặc nếu đối tượng chưa được khởi tạo, một chương trình yêu cầu chuyển đổi này có hành vi không được thực hiện.
Câu hỏi sau đó là liệu một đối tượng là thành viên công đoàn không hoạt động có được khởi tạo bằng cách lưu trữ cho thành viên công đoàn đang hoạt động hay không. Theo như tôi có thể nói, đây không phải là trường hợp và mặc dù vậy:
- một liên minh được sao chép vào
char
bộ lưu trữ mảng và ngược lại (3.9: 2), hoặc
- một liên minh được tạm dừng sao chép sang một liên minh khác cùng loại (3.9: 3), hoặc
- một liên kết được truy cập qua các ranh giới ngôn ngữ bởi một yếu tố chương trình tuân thủ ISO / IEC 9899 (cho đến khi được xác định) (3.9: 4 lưu ý 42), sau đó
truy cập vào một liên minh bởi một thành viên không hoạt động được xác định và được xác định để tuân theo biểu diễn đối tượng và giá trị, truy cập mà không có một trong các can thiệp trên là hành vi không xác định. Điều này có ý nghĩa đối với các tối ưu hóa được phép thực hiện trên một chương trình như vậy, vì việc triển khai dĩ nhiên có thể cho rằng hành vi không xác định không xảy ra.
Đó là, mặc dù chúng ta có thể tạo thành một giá trị hợp pháp cho một thành viên công đoàn không hoạt động (đó là lý do tại sao việc giao cho một thành viên không hoạt động mà không xây dựng là ok) nó được coi là không được khởi tạo.