2015-05-14 25 views
10

Trong mã này, tất cả 100 mục của C.B có được khởi tạo bằng không?Sẽ {0, 0} khởi tạo mảng trong cấu trúc?

struct A { int B[100]; int D; }; 
A C = {0, 0}; 

Có vẻ như hoạt động, nhưng bộ nhớ có thể bị trống trước.

+0

Đây không phải là bản sao, bạn có thể thấy sự khác biệt giữa khởi tạo mảng và cấu trúc không? – exebook

+0

'A C = {0};' thực hiện khởi tạo giá trị của một tổng hợp, do đó nó có giá trị khởi tạo mỗi thành viên. Vì vậy, thực sự mảng thành viên thực sự là zeroed. – vsoftco

+0

@vsoftco, thay vào đó nó có phải là {{0}} không? – exebook

Trả lời

5

Dòng

A C = {0, 0}; 

Thực hiện value initialization của aggregateA. Theo tiêu chuẩn, niềng răng có thể bỏ qua để khởi tạo tổng hợp:

8.5.1 Uẩn [dcl.init.aggr]/12

Niềng răng có thể được elided trong một initializer-list như sau . Nếu danh sách khởi tạo bắt đầu bằng dấu ngoặc nhọn bên trái, thì danh sách các điều khoản khởi tạo được phân tách bằng dấu phẩy khởi tạo thành viên một phân nhóm con mới; nó là sai lầm khi có nhiều hơn điều khoản khởi tạo hơn các thành viên. Tuy nhiên, nếu danh sách khởi tạo cho tổng hợp phụ không bắt đầu bằng dấu ngoặc nhọn, thì chỉ đủ điều khoản khởi tạo từ danh sách được thực hiện để khởi tạo các thành viên của phân nhóm; bất kỳ điều khoản khởi tạo còn lại nào là còn lại để khởi tạo thành viên tiếp theo của tổng hợp trong đó tổng số hiện tại là là một thành viên.

[Ví dụ:

float y[4][3] = { 
    { 1, 3, 5 }, 
    { 2, 4, 6 }, 
    { 3, 5, 7 }, }; 

là một khởi hoàn toàn-chuẩn bị tinh thần: 1, 3 và 5 khởi tạo hàng đầu tiên của mảng y [0], cụ thể là y [0] [0], y [0] [1] và y [0] [2]. Tương tự, hai dòng tiếp theo khởi tạo y [1] và y [2]. Trình khởi tạo kết thúc sớm và do đó các phần tử y [3] là được khởi tạo như thể được khởi tạo một cách rõ ràng với một biểu thức của float dạng (), có nghĩa là, được khởi tạo với 0.0. Trong ví dụ sau , các dấu ngoặc trong danh sách khởi tạo được ưu tiên; tuy nhiên initializer-list có tác dụng tương tự như hoàn toàn-chuẩn bị tinh thần initializer-danh sách các ví dụ trên,

float y[4][3] = { 
    1, 3, 5, 2, 4, 6, 3, 5, 7 }; 

Các initializer cho y bắt đầu với một cú đúp trái, nhưng một cho y [0] không không, do đó ba yếu tố từ danh sách được sử dụng. Tương tự, ba bước tiếp theo được thực hiện liên tiếp cho y [1] và y [2]. - Cuối dụ]

Tiếp

8.5.1 Uẩn [dcl.init.aggr]/7

Nếu có ít initializer-khoản trong danh sách hơn có thành viên trong tổng hợp, sau đó mỗi thành viên không được khởi tạo rõ ràng sẽ được khởi tạo từ trình khởi tạo dấu ngoặc đơn hoặc bằng hoặc nếu có không có bộ khởi tạo dấu ngoặc đơn hoặc bằng, từ danh sách bộ khởi tạo trống.

Trong trường hợp của bạn, điều này có nghĩa là 0 đầu tiên được gán cho B[0] và thứ hai 0 được gán cho B[1]. Theo đó, đến 8.5.1/7, phần còn lại của các phần tử được khởi tạo giá trị.

Tuy nhiên, cho rõ ràng trong trường hợp này, bạn nên sử dụng A C = {{0}, 0};, hoặc tốt hơn

A C{}; // or A C = {}; 

Điều duy nhất mà tôi lo lắng một chút là g ++ cảnh báo (-Wextra):

cảnh báo : thiếu initializer cho thành viên 'chính() :: A :: D' [-Wmissing-field-initializers] AC {0,0};

Nhưng theo cách giải thích của tôi về tiêu chuẩn ở trên, bạn nên OK và D phải được khởi tạo. Tôi thậm chí đã thử nghiệm nó với một số vị trí new và kết quả như mong đợi

#include <iostream> 

int main() 
{ 
    struct A { int B[100]; int D;}; 
    A memory{}; 
    memory.D = 42; 
    std::cout << memory.D << std::endl; 

    // let's place something an A at the location of memory 
    A* foo = new (&memory) A{0,0}; 
    // line below outputs 0, so D is erased; not the case if A* foo = new (&memory) A; 
    std::cout << memory.D << std::endl; // outputs 0 
} 
+1

Tôi đã chỉnh sửa câu hỏi, vì vậy nó không còn {0} nữa, nhưng {0,0}. Bằng cách này nó làm cho sự cân nhắc thực tế của tôi rõ ràng hơn. – exebook

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