Почему sizeof называется оператором времени компиляции?

12

Первоначально это часть другого вопроса.

Почему sizeofназывается оператором времени компиляции? Разве это не на самом деле оператор во время выполнения? И если это действительно оператор времени компиляции, как он помогает в создании переносимого кода, который выполняется одинаково на разных компьютерах? Пожалуйста, объясните подробно.

Мирный Кодер
источник
4
подробно ответил на SO: почему sizeof (x ++) не увеличивает x?
комнат
3
Как вы ожидаете, что размер типа изменится во время выполнения?
@MichaelT: Размер экземпляра типа, безусловно, может измениться - в конце концов, существует полиморфизм классов. Я бы сказал, что sizeof(polymorphic_ptr*)быть постоянным довольно нелогично и просто глупо. Да, это путь C ++, но тем не менее глупо.
Восстановить Монику
@KubaOber Действительно. Мне просто любопытно, как ФП думал, что он должен вести себя в разных случаях, и, надеюсь, получить некоторый код, который продемонстрировал бы его путаницу по этому поводу, чтобы помочь расширить вопрос.
4
Пришел, чтобы поднять ответ «потому что он работает во время компиляции», оставил разочарованным.
Бен Джексон,

Ответы:

23

sizeof()дает вам размер типа данных , а не размер конкретного экземпляра этого типа в памяти.

Например, если у вас был объект строковых данных, который выделял массив символов переменного размера во время выполнения, его sizeof()нельзя было бы использовать для определения размера этого массива символов. Это только даст вам размер указателя.

Размер типа данных всегда известен во время компиляции.


источник
3
Поскольку C (++) не имеет метаданных объекта времени выполнения, вы не можете получить эти вещи также во время выполнения.
К. Росс
5
На самом деле, если вы используете sizeofна массиве, вы будете получить размер массива (то есть раз размера элемента числа элементов). Но если вы используете его для указателя, вы получите только размер указателя. Итак, поскольку в большинстве случаев, когда вы хотите узнать размер массива, у вас есть только указатель, это не так уж и полезно.
sepp2k
1
@Jens Вопрос помечен [C ++], и VLA не вошел в стандарт C ++.
authchir
13

потому что весь размер "вызова" вычисляется во время компиляции, а все, что находится в скобках, отбрасывается и не выполняется во время выполнения,

результат основан исключительно на статической информации о типе, доступной компилятору

чокнутый урод
источник
7

Почему sizeof называется оператором времени компиляции?

Потому что во время компиляции компилятор вычисляет размер выражения и подставляет это значение постоянной времени компиляции.

Разве это не оператор во время выполнения?

Нет. Вы можете даже использовать, sizeofчтобы оценить размер выражений, которые вы не можете выполнить на законных основаниях (т. Е. Это может привести к неопределенному поведению), при условии, что компилятор может выяснить, каков тип выражения.

Кроме того, даже до C ++ 11 constexprвы можете использовать sizeofвыражения так, как вы не можете использовать выражения во время выполнения.

И если это действительно оператор времени компиляции, как он помогает в создании переносимого кода ...

Типы могут различаться по размеру на разных платформах. Использование sizeofвыражений вместо жестко заданных допущений означает, что ваш код не сломается, когда вы компилируете на другой платформе и ваши типы изменят размер.

Бесполезный
источник
1
Ну, я считаю, что это самый полезный ответ;). Братан (предполагая, что вы мужчина), у меня есть сомнения. Вы хотите сказать, что когда люди говорят, что sizeof делает программы переносимыми, они подразумевают, что исходный код может быть скомпилирован без каких-либо ошибок на всех машинах, и они не означают, что исполняемая программа может быть запущена на любой машине. Правильно ? Если это правильно, мои сомнения действительно проясняются.
Мирный кодер
1
Да, код переносим, ​​в том смысле, что вы можете скомпилировать (разные) правильные двоичные файлы для каждой платформы.
бесполезно
5

C ++ на самом деле не хранит метаданные для объектов во время выполнения, поэтому проверка размера должна выполняться во время компиляции. В качестве примера того, как C ++ не проверяет размер, объявите массив intпроизвольного размера и прочитайте его до конца. Если вам повезет, вы получите, segfaultно, скорее всего, просто прочитаете бред, потому что C ++ не отслеживает размер вашего массива.

См. Может ли программная ошибка на языке Си / Си ++ читать после конца массива (UNIX)? для примера из SO.

Пересекать
источник