2012-03-20 47 views
47

Tôi đã xem mã này trên reddit. Tôi đã nghĩ rằng các loại chuyển đổi sẽ khiến điều này không hợp lệ.Tại sao điều này hợp lệ C

int a[3] = { { {1, 2}, {3, 4}, 5, 6 }, {7, 8}, {9}, 10 }; 

Trên tiếng kêu, tôi nhận được một vài cảnh báo về các yếu tố quá mức và dấu ngoặc trong bộ khởi tạo vô hướng. Nhưng nội dung của a[1, 7, 9].

Điều này thực sự hợp pháp, và nếu có, ai đó có thể giải thích chính xác những gì đang xảy ra không?

+5

+1, thật thú vị. – ApprenticeHacker

+4

Với gcc tôi nhận được 24 Cảnh báo. Câu hỏi tuyệt vời. Tôi sống & học :-) – gbulmer

+1

Yay gcc! Ít nhất bạn sẽ nhận được một cảnh báo. – boatcoder

Trả lời

28

Các phần tử thừa chỉ bị bỏ qua. Có hai phần của 6.7.8 Khởi tạo mà bạn quan tâm. Đầu tiên, từ đoạn 17:

Mỗi danh sách bộ khởi tạo kèm cặp đôi có đối tượng hiện tại liên quan. Khi không có chỉ định nào, các đối tượng con của đối tượng hiện tại được khởi tạo theo thứ tự theo loại đối tượng hiện tại: phần tử mảng trong thứ tự tăng thứ tự, cấu trúc thành viên theo thứ tự khai báo và thành viên được đặt tên đầu tiên của công đoàn.

Điều đó giải thích lý do bạn nhận được 1, 7 và 9 - đối tượng hiện tại được đặt bởi các dấu ngoặc nhọn đó. Sau đó, tại sao nó không quan tâm đến các tính năng bổ sung, từ đoạn 20:

... chỉ có đủ trình khởi tạo từ danh sách được tính đến cho các thành phần hoặc thành viên của phân nhóm hoặc thành viên đầu tiên của chứa công đoàn; bất kỳ bộ khởi tạo còn lại nào còn lại để khởi tạo phần tử tiếp theo hoặc thành viên của tập hợp tổng hợp hiện tại hoặc liên kết chứa một phần.

+0

Nhưng tại sao? Và tại sao nó hợp lệ để vượt qua các phần tử lồng nhau mà không có các kiểu struct/union/class? – ams

+1

bạn có muốn chia sẻ url của tiêu chuẩn bạn đang trích dẫn không? – dldnh

+0

[Liên kết PDF.] (Http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf) –

2
int a[3] = { { {1, 2}, {3, 4}, 5, 6 }, {7, 8}, {9}, 10 }; 

không hợp lệ.

Đó là không hợp lệ vì những lý do tương tự int b[1] = {1, 2}; không hợp lệ: vì C99 nói

(C99, 6.7.8p1) "Không initializer sẽ cố gắng để cung cấp một giá trị cho một đối tượng không nằm trong các thực thể được khởi tạo . "

Thành phần cuối cùng cố gắng cung cấp giá trị cho đối tượng không chứa trong thực thể được khởi tạo.

+0

Tôi rất muốn nghe một cuộc tranh luận tốt về các xác nhận khác nhau được thực hiện bởi tài liệu tham khảo bạn đã trích dẫn, và tham chiếu thứ hai được trích dẫn bởi Carl. Dường như là một xung đột rõ ràng trong các tiêu chuẩn, có khả năng sẽ dẫn đến sự khác biệt trong việc triển khai trình biên dịch cho đến khi nó được giải quyết. 1 để chỉ ra sự khác biệt. – ryyker

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