Нижче не вдається скомпілювати:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
але якщо я зміню його на
sizeof(arr);
все добре. Чому?
Нижче не вдається скомпілювати:
typedef int arr[10];
int main(void) {
return sizeof arr;
}
sizeof.c:3: error: expected expression before ‘arr’
але якщо я зміню його на
sizeof(arr);
все добре. Чому?
sizeof
принципово те саме, що робить сьогодні C99 Standard. sizeof
доступний ще до того, як C був стандартизований ANSI у 1989 р.
Відповіді:
Відповідно до 6.5.3, існують дві форми sizeof
:
sizeof unary-expression
sizeof ( type-name )
Оскільки arr
у вашому коді є a type-name
, він повинен бути в дужках.
sizeof
є оператором: дужки "належать" типу, а не оператору.
sizeof
як оператора.
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?
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.
sizeof ( type-name )
це власним висловом. (Стандарт називає це оператором, але ( type-name )
насправді не є операндом у звичному розумінні.)
Саме так вказана мова, імена типів тут мають бути в дужках.
Припустимо, граматика виглядала так:
sizeof unary-expression
sizeof type-name
Тепер, наприклад, такий вираз буде неоднозначним:
sizeof int * + 0
Це може бути або sizeof(int *) + 0
абоsizeof(int) * +0
. Ця неоднозначність не виникає для одинарних виразів, оскільки зірочка, що додається до виразу, не є виразом (але для деяких імен типів, що додають, знову є ім'ям типу).
Тут потрібно було щось вказати, і вимагати, щоб імена типів були в дужках - це спосіб вирішити двозначність.
Я думаю, це тому, що у вас є typedef
. Якщо ви видалите його, він повинен скомпілюватись.
Приклад з Вікіпедії:
/* 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));