2013-08-19 38 views
14

Lưu ý: Chúng tôi đang nói về (được cho là) ​​C++ 98 trình biên dịch tuân thủ, ở đây. Đây không phải là câu hỏi C++ 11.C++ mảng zero-initialization: Đây có phải là lỗi hay chính xác không?

Chúng tôi có một hành vi kỳ lạ trong một trong các trình biên dịch của chúng tôi và chúng tôi không chắc chắn nếu điều này là Ok hoặc nếu đây là một trình biên dịch lỗi:

// This struct has a default constructor 
struct AAA 
{ 
    AAA() : value(0) {} 
    int value ; 
} ; 

// This struct has a member of type AAA and an array of int, both surrounded 
// by ints 
struct BBB 
{ 
    int m_a ; 
    AAA m_b ; 
    int m_c ; 
    int m_d[42] ; 
} ; 

Khi BBB được khởi tạo như vậy:

BBB bbb = {0} ; 

Chúng tôi dự kiến ​​tất cả các thành viên POD của BBB (bao gồm m_d, mảng int) sẽ không được khởi tạo, và tất cả các thành viên không phải POD của BBB sẽ được xây dựng.

Điều này làm việc trên trình biên dịch gốc của AIX, trên Linux/GCC-3.4, trên Windows/VisualC++ ... Nhưng không phải trên Solaris/SunStudio, nơi chỉ thành viên không phải mảng không được khởi tạo.

Chúng tôi đã nghiên cứu một chút, trong tiêu chuẩn C++ 98 (một dự thảo văn bản), nơi mà chúng tôi tìm thấy những điều sau đây:

[12.6.1 - 2]

Khi một tổng hợp (cho dù lớp hoặc mảng) có chứa các thành viên của kiểu lớp và được khởi tạo bởi một danh sách khởi tạo kèm cặp ngoặc đơn (8.5.1), mỗi thành viên đó được sao chép-khởi tạo (xem 8.5) bằng biểu thức gán tương ứng. Nếu có ít bộ khởi tạo trong danh sách khởi tạo hơn các thành viên của tổng hợp, mỗi thành viên không được khởi tạo rõ ràng sẽ được khởi tạo mặc định (8.5).

Sau đó:

[8,5-5]

Để zero-khởi lưu trữ cho một đối tượng kiểu T có nghĩa là:
- nếu T là một kiểu vô hướng (3.9), bộ nhớ được đặt thành giá trị 0 (không) được chuyển thành T;
- nếu T là loại không thuộc loại công đoàn, dung lượng lưu trữ cho mỗi thành viên dữ liệu không phải là thành phần và mỗi lớp con cấp cơ sở không được khởi tạo;
- nếu T là loại công đoàn, dung lượng lưu trữ cho thành viên dữ liệu đầu tiên 89) không được khởi tạo;
- nếu T là một loại mảng, dung lượng lưu trữ cho từng phần tử không được khởi tạo;
- nếu T là kiểu tham chiếu, thì không khởi tạo được thực hiện.

Và sau đó:

Để mặc định-khởi một đối tượng kiểu T có nghĩa là:
- nếu T là một tổ chức phi POD kiểu lớp (khoản 9), các nhà xây dựng mặc định cho T được gọi (và khởi tạo bị hỏng nếu T không có hàm tạo mặc định có thể truy cập);
- nếu T là một loại mảng, mỗi phần tử được khởi tạo mặc định;
- nếu không, bộ nhớ cho đối tượng không được khởi tạo.

Con đường tôi đọc nó: SunStudio nên zero-khởi tạo mảng ints (BBB :: m_d)

Lạ một điều: nếu chúng ta loại bỏ các constructor mặc định từ AAA, sau đó tất cả mọi thứ trong BBB là không được khởi tạo.

CÂU HỎI: Chuẩn mực hành vi của SunStudio khi không thể khởi tạo một mảng ints của một cấu trúc có chứa một POD không? Hay đây là lỗi trình biên dịch?

+4

Có vẻ như một lỗi với tôi. Nếu bạn viết 'BBB bbb = {0,0,0, {0}};' –

+10

Đó là lỗi trong CN CC. Sự hiểu biết của bạn về tiêu chuẩn là chính xác. –

+0

@ JamesKanze: Tôi thực sự không thể đưa ra nhận xét, cũng không chọn chúng làm câu trả lời ... đừng ngần ngại trả lời đầy đủ ... :-) – paercebal

Trả lời

2

Nó thực sự là lỗi với Sun/Solaris. Những gì bạn đã viết thực sự là những gì được cho là xảy ra và bạn chính xác với mọi thứ bạn viết.

1

Đây rõ ràng là lỗi trong CN CC. Tiêu chuẩn là rõ ràng, và sự hiểu biết của bạn về nó là chính xác.

1

Nó có vẻ là một lỗi - Tôi không có kinh nghiệm với các trình biên dịch Solaris, nhưng tất cả các trình biên dịch khác mà tôi đã làm việc với sẽ cho phép loại khởi tạo này.

tôi sẽ đề nghị rằng việc xung quanh vấn đề bằng cách rõ ràng hơn:

BBB bbb = {0, 0, 0, {0} }; 
Các vấn đề liên quan