2015-06-24 16 views
19

Tôi biết rằng sizeof không bao giờ đánh giá toán hạng của nó, ngoại trừ trong trường hợp cụ thể khi toán hạng được nói là VLA. Hoặc, tôi nghĩ Tôi biết.VLAs và tác dụng phụ trong toán hạng của sizeof

void g(int n) { 
    printf("g(%d)\n", n); 
} 

int main(void) { 
    int i = 12; 

    char arr[i]; // VLA 

    (void)sizeof *(g(1), &arr); // Prints "g(1)" 
    (void)sizeof (g(2), arr); // Prints nothing 

    return 0; 
} 

Điều gì đang xảy ra?

Chỉ trong trường hợp, điều này được biên dịch bằng GCC 5.1 trên Coliru.

Trả lời

18

Có vẻ như tôi nên suy nghĩ kỹ trước khi đăng bài, vì nó đã đánh tôi ngay sau khi tôi làm vậy.

hiểu biết của tôi về cách sizeof tương tác với Vlas là thực sự đúng, như này khẳng định quote sau (nhờ @this!):

6.5.3.4 Các sizeof_Alignof khai thác
Nếu kiểu của toán hạng là một loại mảng có độ dài biến đổi, toán hạng được đánh giá; nếu không, toán hạng không được đánh giá và kết quả là hằng số nguyên

Đó không phải là điều gây ra hành vi đáng ngạc nhiên (đối với tôi) này.

(void)sizeof (g(2), arr); 

Trong (g(2), arr) subexpression, các nhà điều hành dấu phẩy gây arr 's mảng-to-con trỏ phân rã. Do đó, toán hạng của sizeof không còn là VLA nữa, mà là một đơn vị char* đơn giản và nó quay trở lại để không đánh giá toán hạng của nó.

Apparently hành vi này đã bị thay đổi trong C++, trong đó toán tử dấu phẩy sẽ không phân rã mảng nữa.

+2

Một lần, một trường hợp tốt để trả lời câu hỏi của riêng bạn. – Bathsheba

+2

Bạn có thể muốn thêm điều này ở đâu đó: * 6.5.3.4 Các toán tử sizeof và _Alignof Nếu kiểu toán hạng là một mảng có độ dài biến là loại , toán hạng được đánh giá; nếu không, toán hạng không được đánh giá và kết quả là hằng số nguyên . * vì vậy, người đọc sốt sẽ bị nhầm lẫn. – this

+0

@ this Cảm ơn bạn :) – Quentin

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