2012-01-14 36 views
9

This answer of mine tạo ra một số ý kiến ​​cho rằng các cấu trúc sau đây không phải là quy phạm pháp luật C/C++:Đây có phải là C/C++ hợp pháp không? 'Int * p = (int []) {1,2,3}; `

void f (int* a) ; 
f ((int[]){1,2,3,4,0}) ; 

(thấy this ideone link cho đầy đủ chương trình). Nhưng chúng tôi không thể giải quyết vấn đề. Ai có thể làm sáng tỏ điều này không? Các tiêu chuẩn khác nhau phải nói gì?

+0

Tôi nghĩ @Nicol Bolas là đúng, người đã nhận xét về bài đăng của bạn. Không phải mọi thứ hoạt động, đều hợp lệ. Điều đó thực sự thường xảy ra. Tôi sẽ nói đoạn trích trong nhận xét của bạn dẫn đến 'hành vi không xác định'. Vì vậy, nếu bạn muốn chứng minh anh ta là hợp pháp, bạn phải lấy ra/tìm kiếm trong tiêu chuẩn c/C++/C++ 11. – poitroae

+0

@Michael: Tôi không muốn chứng minh nó là hợp pháp, tôi chỉ muốn biết liệu nó có hợp pháp hay không. Các ý kiến ​​cho bài viết của tôi (bao gồm cả ý kiến ​​của tôi) chỉ là ý kiến. – TonyK

+0

Tại sao hành vi không xác định? –

Trả lời

9

Đó là hợp lệ C99 theo như tôi có thể nói - đó là đi qua một chữ hợp chất.

tiêu chuẩn Các C99 có này là một ví dụ (§6.5.2.5/9):

VÍ DỤ 1 Định nghĩa phạm vi tập tin

int *p = (int []){2, 4}; 

khởi p để trỏ đến phần tử đầu tiên của một mảng gồm hai int, giá trị đầu tiên có giá trị hai và số thứ hai, bốn. Các biểu thức trong hợp chất này được yêu cầu phải là hằng số. Đối tượng chưa đặt tên có thời gian lưu trữ tĩnh.

Lưu ý rằng điều (int []) không phải là diễn viên ở đây.

Đây không phải là cấu trúc C++ hợp lệ, mặc dù các chữ ghép hợp chất không phải là một phần của tiêu chuẩn C++ (bao gồm C++ 11). Một số trình biên dịch cho phép nó như là một phần mở rộng. (GCC không, vượt qua -Wall -pedantic để có được một chẩn đoán về nó. IBM XLC allows it as an extension too.)

+2

Lưu ý rằng đối tượng mảng có thời gian lưu trữ tĩnh chỉ khi nó ở phạm vi tệp, như trong ví dụ. Nếu nó xuất hiện bên trong một định nghĩa hàm, thì nó có thời gian lưu trữ tự động kết hợp với khối bao quanh (tức là đối tượng và bất kỳ con trỏ nào đến nó trở thành không hợp lệ khi thực thi đạt đến '}' kèm theo). Điều này không giống như các chuỗi ký tự chuỗi, luôn có thời lượng lưu trữ tĩnh. –

+0

Cảm ơn! Điều đó dường như bao gồm mọi thứ. – TonyK

+0

Thời gian lưu trữ nào sẽ là 'char * p = (char []) {'s', 't', 'r', 'i', 'n', 'g', 0}' có? – hirschhornsalz

-1

Vâng, tôi nghĩ nó hợp lệ theo C++ 11. Phần 5.2:

postfix-expression: 
    ... 
    typename-specifier (expression-listopt) 
    simple-type-specifier braced-init-list 
    typename-specifier braced-init-list 
    ... 
expression-list: 
    initializer-list 

EDIT: Sau khi một số đọc tôi càng đi đến kết luận nó thực sự không hợp lệ, bởi vì bạn không thể sử dụng biểu postfix như thế. Nên có một số biểu hiện chính.

+1

Bạn có thể báo giá. Và tôi không thấy bất cứ điều gì ở đó làm cho điều này hợp lệ. –

+0

Đoạn trích bạn đã đăng không khớp với câu hỏi. Nếu bạn quan tâm, loại cú pháp đúc này nằm trong §5.4 không §5.2.Bạn cũng nên đọc qua các chuyển đổi được phép và bạn sẽ thấy rằng bạn không được phép truyền vào một loại mảng. –

+0

@R. Martinho Fernandes: Bây giờ tôi đang bối rối. Tôi nghĩ rằng 'typename-specifier braced-init-list' có thể viết eq. như 'sometype {1, 2, 3, 4}', nhưng gcc không cho phép tôi làm điều này. Đây có phải là chỉ cho cấu trúc, hoặc tôi hoàn toàn sai? – stativ

1

Khái niệm trôi qua như là đối số cho hàm là một ví dụ về một hợp chất đen. Đây là hợp pháp trong C99, nhưng không phải trong C++ 98.

Xem ví dụ phần 6.4.4 "Hằng số" và 6.8 "Báo cáo và khối" trong N897 "A draft rationale for the C99 standard." Xem thêm this section tài liệu GCC.

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