Почему sizeof считается оператором?

95

Почему sizeofсчитается оператором, а не функцией?

Какое имущество необходимо для квалификации оператора?

Арпит
источник

Ответы:

183

Потому что стандарт C так говорит, и он получает единственный голос.

В качестве последствий:

  • Операнд sizeof может быть заключенным в скобки типом sizeof (int), а не выражением объекта.
  • Скобки не нужны: int a; printf("%d\n", sizeof a);все в порядке. Их часто можно увидеть, во-первых, потому что они необходимы как часть выражения приведения типа, а во-вторых, потому что sizeof имеет очень высокий приоритет, поэтому sizeof a + bэто не то же самое, что sizeof (a+b). Но они не являются частью вызова sizeof, они являются частью операнда.
  • Вы не можете взять адрес sizeof.
  • Выражение, которое является операндом sizeof, не оценивается во время выполнения ( sizeof a++не изменяет a).
  • Выражение, являющееся операндом sizeof, может иметь любой тип, кроме типов void или функций. Действительно, в этом и смысл sizeof.

Функция будет отличаться по всем этим пунктам. Вероятно, есть и другие различия между функцией и унарным оператором, но я думаю, что этого достаточно, чтобы показать, почему sizeof не может быть функцией, даже если для этого была причина.

Стив Джессоп
источник
3
Вау, о чем я думал!
crashmstr
7
Не могу сказать лучше.
Клемент Херреман,
Я считаю, что в наши дни все стало сложнее из-за массивов переменной длины (VLA). IIRC, стандарт даже допускает sizeofпобочные эффекты, если в выражении присутствует VLA.
Аарон МакДэйд
@glglgl Нет, в этом нет никакого смысла. В этом контексте (int)нет ничего необычного - просто название типа в круглых скобках. Круглые скобки здесь являются частью синтаксиса sizeof- они требуются при выборе размера типа, но не требуются при выборе размера выражения. См., Например, здесь
анатолий 07
1
В стандарте используются две нотации sizeof: sizeof unary-expressionи sizeof ( type-name )- поэтому в стандарте C11 это считается не «приведением», а именем типа в скобках. Чистый результат примерно такой же. (Для сравнения, выражение приведения - это ( type-name ) cast-expression.) И мне не нравится то, как Markdown комментариев работает не так, как Markdown в вопросах и ответах!
Джонатан Леффлер
24

Его можно использовать как константу времени компиляции, что возможно, только если это оператор, а не функция. Например:

union foo {
    int i;
    char c[sizeof(int)];
};

Синтаксически, если бы это не был оператор, это должен был бы быть макрос препроцессора, поскольку функции не могут принимать типы в качестве аргументов. Этот макрос сложно реализовать, поскольку он sizeofможет принимать в качестве аргумента как типы, так и переменные.

Джон Кугельман
источник
4
+1, но обратите внимание, что это не константа времени компиляции, когда аргументом является VLA-массив переменной длины.
Джонатан Леффлер,
6

Потому что стандарт C так говорит, и он получает единственный голос.

И стандарт, вероятно, правильный, потому что sizeofпринимает тип и

В общем случае, если домен или домен (или оба) функции содержат элементы, значительно более сложные, чем действительные числа, эта функция называется оператором. И наоборот, если ни область, ни область значений функции не содержат элементов более сложных, чем действительные числа, эта функция, вероятно, будет называться просто функцией. Тригонометрические функции, такие как косинус, являются примерами последнего случая.

Кроме того, когда функции используются так часто, что их нотации развиваются быстрее или проще, чем общая форма F (x, y, z, ...), полученные специальные формы также называются операторами. Примеры включают инфиксные операторы, такие как сложение «+» и деление «/», и постфиксные операторы, такие как факториал «!». Это использование не связано со сложностью задействованных сущностей.

(Википедия)

Даниэль Брюкнер
источник
Это, вероятно, объясняет мотивацию стандарта C (и других языков программирования) к использованию терминов «оператор» и «функция», как они это делают.
Стив Джессоп
5

Потому что это не функция. Вы можете использовать это так:

int a;
printf("%d\n", sizeof a);

У функции есть точка входа, код и т. Д. Функция должна запускаться во время выполнения (или встраиваться), размер sizeof должен быть определен во время компиляции.

Михал Горный
источник
2

Оператор sizeof - это объект времени компиляции, а не время выполнения, и ему не нужны круглые скобки, как функция. Когда код компилируется, он заменяет значение размером этой переменной во время компиляции, но в функции после выполнения функции мы узнаем возвращаемое значение.

Дипак Кумар 'СОРТИРОВАННЫЙ'
источник
1

Так как:

  • когда вы передаете значение функции, размер объекта не передается в функцию, поэтому sizeof«функция» не сможет определить размер
  • в C функции могут принимать только один тип аргументов; sizeof () должен принимать всевозможные разные вещи (переменные, а также типы! Вы не можете передать тип функции в C)
  • вызов функции включает создание копии аргументов и других ненужных накладных расходов
Artelius
источник
1

Есть небольшое отличие от функции - значение sizeof разрешается во время компиляции, но не во время выполнения!

Dewfy
источник
7
Кроме VLA - массив переменной длины - аргументы.
Джонатан Леффлер,
1

Поскольку это оператор времени компиляции, который для вычисления размера объекта требует информации о типе, доступной только во время компиляции. Это не относится к C ++.

Жоао Силва
источник
0

sizeof()оператор - это время компиляции. Его можно использовать для определения параметров или аргументов.

ганеш
источник
-1

Sizeof (), я думаю, очевидно, что это и функция, и оператор. Зачем? Потому что функция содержит круглые скобки для ввода на этапе ввода. Но в основном также операторы, вызывающие операторы, являются символом действия, поэтому sizeof - это оператор действия, который действует на операнд в круглых скобках.

Зал Еноха Асанды
источник