Чому sizeof вважається оператором?


93

Чому sizeofвважається оператором, а не функцією?

Яка властивість необхідна для кваліфікації оператора?

Відповіді:


181

Тому що стандарт С говорить так, і він отримує єдиний голос.

Як наслідки:

  • Операнд 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 не може бути функцією, навіть якщо була причина, щоб це хотілося.


3
Ого, саме про що я думав!
crashmstr

7
Краще сказати не можу.
Clement Herreman

Я вважаю, що сьогодні все складніше через масиви змінної довжини (VLA). IIRC, стандарт навіть дозволяв sizeofби мати побічні ефекти, якщо у виразі є VLA.
Аарон Макдейд

@glglgl Ні, це не має жодного сенсу. У цьому контексті (int)немає нічого вигадливого - просто назва типу в дужках. Дужки тут є частиною синтаксису sizeof- вони потрібні при прийнятті розміру типу, але не потрібні при прийнятті розміру виразу. Дивіться, наприклад, тут
anatolyg

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

Тому що стандарт С говорить так, і він отримує єдиний голос.

І стандарт, мабуть, правильний, оскільки sizeofбере тип і

Загалом, якщо або домен, або кодомен (або обидва) функції містять елементи, значно складніші від дійсних чисел, ця функція називається оператором. І навпаки, якщо ні домен, ні кодомен функції не містять елементів, більш складних, ніж реальні числа, ця функція, швидше за все, буде називатися просто функцією. Тригонометричні функції, такі як косинус, є прикладами останнього випадку.

Крім того, коли функції використовуються настільки часто, що вони еволюціонували швидше або легше, ніж загальна форма F (x, y, z, ...), отримані спеціальні форми також називаються операторами. Прикладом можуть бути оператори інфіксу, такі як додавання "+" та поділ "/", та оператори постфіксу, такі як факторіал "!". Це використання не пов’язане зі складністю залучених суб’єктів.

(Вікіпедія)


Це, мабуть, пояснює мотивацію стандарту С (та інших мов програмування) у використанні термінів "оператор" та "функція", як вони це роблять.
Steve Jessop

5

Тому що це не функція. Ви можете використовувати його так:

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

Функція має точку входу, код тощо. Функція повинна запускатися під час виконання (або вбудована), розмір повинен визначатися під час компіляції.


2

sizeof - оператор часу компіляції, а не час виконання і не потребує дужок, як функція. Коли код компілюється, він замінює значення на розмір цієї змінної під час компіляції, але у функції після того, як функція виконується, тоді ми будемо знати повертається значення.


1

Тому що:

  • коли ви передаєте значення функції, розмір об'єкта не передається функції, тому sizeof"функція" не може визначити розмір
  • в C функції можуть приймати лише один тип аргументу; sizeof () повинен приймати всілякі речі різної мережі (змінні, а також типи! Ви не можете передати тип функції у C)
  • виклик функції передбачає копіювання аргументів та інші непотрібні накладні витрати

1

Існує невелике відхилення від функції - значення sizeof вирішується під час компіляції, але не під час виконання!


7
За винятком VLA - масив змінної довжини - аргументи.
Джонатан Леффлер

1

Оскільки це оператор часу компіляції, який для обчислення розміру об’єкта вимагає інформації про тип, яка доступна лише під час компіляції. Це не стосується C ++.


0

sizeof()оператор - це час компіляції. З його допомогою можна визначити параметри або аргументи.


-1

Sizeof (), я думаю, очевидно, що це і функція, і оператор. Чому? Оскільки функція містить дужки для введення на етапі введення. Але в основному також оператори причини оператора мають символ дії, тому sizeof - це оператор дії, який діє на операнд у дужках.

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