Tại sao (và khi nào) tôi cần sử dụng dấu ngoặc đơn sau sizeof?


80

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ới tư cách là một toán tử không có sẵn trong ansi-c
Grim

2
@Kostya: bản sao K&R của tôi (mô tả sớm nhất về ngôn ngữ C mà tôi có) ở rất xa và tôi không thể kiểm tra nó ngay bây giờ, nhưng tôi chắc chắn 110% nó mô tả sizeofvề cơ bản giống như cách C99 Standard hiện nay. sizeofcó sẵn từ trước khi C được ANSI chuẩn hóa vào năm 1989.
pmg

Câu trả lời:


120

Theo 6.5.3, có hai hình thức sizeofnhư sau:

sizeof unary-expression
sizeof ( type-name )

arrmã của bạn là a type-namenên nó phải được đặt trong ngoặc đơn.


15
+1 và, chỉ để củng cố rằng đó sizeoflà một toán tử: dấu ngoặc đơn "thuộc về" loại, không phải toán tử.
pmg

@pmg: Cảm ơn bạn đã làm rõ! Có, như bạn đã đề cập, tiêu chuẩn biểu thị sizeofnhư một toán tử.
Ise Wisteria

4
@pmg: Tôi không nghĩ nó rõ ràng là "thuộc về" cái gì trong ngoặc đơn. Cú pháp của hình thức thứ hai bao gồm ba thẻ và một phi terminal: 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 sizeofkhô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?
Keith Thompson

3
Ý tôi sizeoflà, 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 printfcái đó printf ( <SOMETHING> ). Dấu ngoặc đơn thuộc về printfnhư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.
pmg

2
@pmg: Bạn chắc chắn có thể nghĩ về nó theo cách đó, nhưng tôi thấy nó gây hiểu lầm. Điểm tương đồng thực sự duy nhất với một tập hợp là nó có tên kiểu trong ngoặc đơn và đó chỉ là sự trùng hợp ngẫu nhiên về sự tiện lợi về mặt cú pháp. Tôi thích 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.)
Keith Thompson

44

Đó 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 *) + 0hoặ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ồ.


-3

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));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.