Dưới đây không thể biên dịch:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
nhưng nếu tôi thay đổi nó thành
sizeof(arr);
mọi thứ đều ổn. Tại sao?
Dưới đây không thể biên dịch:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
nhưng nếu tôi thay đổi nó thành
sizeof(arr);
mọi thứ đều ổn. Tại sao?
sizeof
về cơ bản giống như cách C99 Standard hiện nay. sizeof
có sẵn từ trước khi C được ANSI chuẩn hóa vào năm 1989.
Câu trả lời:
Theo 6.5.3, có hai hình thức sizeof
như sau:
sizeof unary-expression
sizeof ( type-name )
Vì arr
mã của bạn là a type-name
nên nó phải được đặt trong ngoặc đơn.
sizeof
là một toán tử: dấu ngoặc đơn "thuộc về" loại, không phải toán tử.
sizeof
như một toán tử.
sizeof ( type-name )
. Nhưng đối với biểu mẫu đầu tiên, bạn có thể viết chẳng hạn, sizeof(x)
và mặc dù nó trông giống như một lệnh gọi hàm (nếu sizeof
không phải là một từ khóa), nó thực sự là một toán tử được áp dụng cho một biểu thức trong ngoặc đơn. Đó có phải là những gì bạn có trong đầu?
sizeof
là, về mặt cú pháp sizeof <SOMETHING>
, chẳng hạn như đối lập với các hàm, đối với một printf
cái đó printf ( <SOMETHING> )
. Dấu ngoặc đơn thuộc về printf
nhưng không thuộc về sizeof
. Khi sizeof
được áp dụng cho một tên kiểu trong ngoặc đơn, tôi muốn nghĩ về nó như một tập hợp không có gì - "trả về" chỉ là kiểu.
sizeof ( type-name )
coi đó là kiểu biểu đạt của riêng nó. (Tiêu chuẩn gọi đó là một nhà điều hành, nhưng ( type-name )
không thực sự là một toán hạng theo nghĩa thông thường.)
Đó là cách ngôn ngữ được chỉ định, tên loại phải được đặt trong ngoặc đơn ở đây.
Giả sử ngữ pháp trông như thế này:
sizeof unary-expression
sizeof type-name
Bây giờ, ví dụ: biểu thức sau sẽ không rõ ràng:
sizeof int * + 0
Nó có thể là một trong hai sizeof(int *) + 0
hoặc sizeof(int) * +0
. Sự không rõ ràng này không nảy sinh đối với các biểu thức một ngôi, vì dấu hoa thị được thêm vào một biểu thức không phải là một biểu thức (nhưng đối với một số tên kiểu, nối một, lại là một tên kiểu).
Một cái gì đó phải được chỉ định ở đây và yêu cầu tên kiểu phải được đặt trong ngoặc đơn là một cách để giải quyết sự mơ hồ.
Tôi nghĩ đó là bởi vì bạn có typedef
. Nếu bạn loại bỏ nó, nó sẽ biên dịch.
Ví dụ từ wikipedia:
/* the following code fragment illustrates the use of sizeof
* with variables and expressions (no parentheses needed),
* and with type names (parentheses needed)
*/
char c;
printf("%zu,%zu\n", sizeof c, sizeof (int));