Чому (і коли) мені потрібно використовувати дужки після sizeof?


80

Нижче не вдається скомпілювати:

але якщо я зміню його на

все добре. Чому?


sizeof як оператор недоступний в ansi-c
Grim

2
@Kostya: моя копія K&R (найдавніший опис мови C, який я маю) дуже далека, і я не можу зараз це перевірити, але я впевнена на 110%, що вона описує sizeofпринципово те саме, що робить сьогодні C99 Standard. sizeofдоступний ще до того, як C був стандартизований ANSI у 1989 р.
pmg

Відповіді:


120

Відповідно до 6.5.3, існують дві форми sizeof:

Оскільки arrу вашому коді є a type-name, він повинен бути в дужках.


15
+1 і лише для того, щоб підсилити, що sizeofє оператором: дужки "належать" типу, а не оператору.
pmg

@pmg: Дякую за роз'яснення! Так, як ви вже згадували, стандарт позначає sizeofяк оператора.
Ісе Гліцинія

4
@pmg: I don't think it's clear what the parentheses "belong to". The syntax of the second form consists of three tokens and one non-terminal: sizeof ( type-name ). But for the first form, you can write, for example, sizeof(x), and though it looks like a function call (if sizeof weren't a keyword), it's really an operator applied to a parenthesized expression. Is that what you had in mind?
Keith Thompson

3
What I mean is that sizeof is, syntactically sizeof <SOMETHING> as opposed to functions, for instance, to a printf which is printf ( <SOMETHING> ). The parenthesis belong to the printf but not to sizeof. When sizeof is applied to a parenthesized type name, I like to think of that as a cast of nothing -- "returning" just the type.
pmg

2
@pmg: Ви, звичайно, можете думати про це так, але я вважаю це оманливим. Єдина реальна схожість з акторським складом полягає в тому, що він має назву типу в дужках, і це просто збіг синтаксичної зручності. Я вважаю за краще вважати sizeof ( type-name )це власним висловом. (Стандарт називає це оператором, але ( type-name )насправді не є операндом у звичному розумінні.)
Кіт Томпсон,

44

Саме так вказана мова, імена типів тут мають бути в дужках.

Припустимо, граматика виглядала так:

sizeof unary-expression sizeof type-name

Тепер, наприклад, такий вираз буде неоднозначним:

Це може бути або sizeof(int *) + 0абоsizeof(int) * +0 . Ця неоднозначність не виникає для одинарних виразів, оскільки зірочка, що додається до виразу, не є виразом (але для деяких імен типів, що додають, знову є ім'ям типу).

Тут потрібно було щось вказати, і вимагати, щоб імена типів були в дужках - це спосіб вирішити двозначність.


-3

Я думаю, це тому, що у вас є typedef . Якщо ви видалите його, він повинен скомпілюватись.

Приклад з Вікіпедії:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.