2017-11-07 15 views
6

Điều gì làm cho một thành viên công đoàn hoạt động?Điều gì làm cho một thành viên công đoàn hoạt động?

Tôi đã đọc chương 9.5 của tiêu chuẩn C++ 14 (một về công đoàn), nhưng tôi chưa tìm thấy câu trả lời rõ ràng cho những gì làm cho thành viên công đoàn hoạt động.

Có một lưu ý:

Nói chung, người ta phải sử dụng các cuộc gọi destructor rõ ràng và vị trí mới nhà khai thác để thay đổi thành viên tích cực của công đoàn.

Vì vậy, ví dụ,

union U { 
    int i; 
    short s; 
} u; 

new(&u.i) int(42); 

Được rồi, vị trí thay đổi mới các thành viên tích cực, rõ ràng. Nhưng chúng ta thường không sử dụng vị trí mới khi làm việc với các loại với các nhà xây dựng tầm thường.

operator= thay đổi thành viên đang hoạt động không có UB?

u.i = 42; 

Ở đây, operator= được gọi là đối tượng không bị cản trở. Nó được xác định rõ?

Điều này thì sao?

struct A { 
    int i0; 
    int i1; 
}; 
union U { 
    A a; 
    short s; 
} u; 

Điều gì làm cho a trở thành thành viên tích cực của u? Cài đặt cả hai i0 & i1 có đủ không?

u.a.i0 = 42; 
u.a.i1 = 99; 

gì nếu tôi viết:

u.a.i0 = 42;  // supposedly this doesn't change the active member to a, as i1 isn't set 
int x = u.a.i0; // is it fine to read from a.i0? a is not an active member supposedly 

Sau u.a.i0 = 42;, các thành viên tích cực không được thay đổi để a (tôi nghĩ), như vậy là nó UB làm int x = u.a.i0;?

C++ 17 có cải thiện mô tả của các thành viên tích cực không?

+0

"Ở đây,' điều hành = 'kêu gọi một unconstructed đối tượng "bạn có chắc không? Đó là POD vì vậy nó có vẻ tốt. – BartoszKP

+1

Định nghĩa Laymen là đây là phần tử được viết cuối cùng. Nhưng tôi không thể tìm thấy bất kỳ sự chứng minh nào trong tiêu chuẩn này. – SergeyA

+0

@BartoszKP: tốt, đó là DynamicType chắc chắn là (?) Không phải 'int', vì vậy ... Tôi không biết :) – geza

Trả lời

5

Trong C++ 17, một đoạn văn đã được bổ sung mà thảo luận một cách rõ ràng những trường hợp như u.i = 42:

[class.union]/5 Khi toán hạng trái của một nhà điều hành phân công liên quan đến một biểu thức truy cập thành viên (8.2.5) đề cử một thành viên công đoàn, nó có thể bắt đầu tuổi thọ của thành viên công đoàn đó, như được mô tả dưới đây. Đối với một biểu E, xác định các thiết lập S(E) của subexpressions của E như sau:

(5,1) - Nếu E có dạng A.B, S(E) chứa các yếu tố của S(A), và cũng chứa A.B nếu B tên thành viên công đoàn của một loại non-array, non-array, hoặc của một kiểu lớp với một constructor mặc định tầm thường không bị xóa hoặc một mảng các kiểu như vậy.

(5.2) - Nếu E có dạng A[B] và được hiểu là toán tử lập chỉ mục mảng tích hợp, S(E)S(A) nếu A thuộc loại mảng, S(B) nếu B thuộc loại mảng và nếu không thì sẽ trống.

(5.3) - Nếu không, S(E) sẽ trống.

Trong một biểu hiện phân công của hình thức E1 = E2 có sử dụng một trong hai nhà điều hành được xây dựng trong phân (8.18) hoặc một toán tử gán tầm thường (15,8), cho mỗi phần tử X của S(E1), nếu sửa đổi X sẽ có hành vi undefined dưới 6,8 , đối tượng thuộc loại X được tạo hoàn toàn trong bộ nhớ được chỉ định; không khởi tạo được thực hiện và bắt đầu của cuộc đời của nó được sắp xếp sau khi tính toán giá trị của toán hạng trái và phải và trước khi gán. [Lưu ý: Điều này kết thúc tuổi thọ của thành viên hoạt động trước đây của công đoàn, nếu có (6.8). -end lưu ý]

(Tiếp theo là một ví dụ hơi dài rằng tôi quá lười biếng để định dạng đúng, nhưng mà bạn có thể nhìn thấy here.)

Các vấn đề liên quan