Какова стоимость sizeof?
Я бы ожидал:
- sizeof (someclass) можно узнать во время компиляции
- sizeof (someStaticArray) можно узнать во время компиляции
- sizeof (someDynamicArray) может быть не во время компиляции
Как работает этот последний случай?
Какова стоимость sizeof?
Я бы ожидал:
Как работает этот последний случай?
Конструкция sizeof
в C является конструкцией времени полной компиляции. Там нет затрат времени выполнения.
Из этого правила есть как минимум одно исключение: массивы переменной длины. Размер этих массивов вычисляются во время выполнения и что размер повторно используется для любых sizeof
операторов, применяемых к ним.
Обратите внимание, что существует разница между массивом переменной длины и динамическим. Массивы переменной длины были добавлены в C99, и они поддерживают оператор sizeof
sizeof(dynamicArray)
просто вернет sizeof(pointer)
, потому что в c/С++ динамические массивы являются просто указателями.
В С++ последний случай не существует. sizeof
всегда можно оценить во время компиляции, основываясь исключительно на типе параметра, поэтому сам параметр никогда не оценивается.
Если вы хотите что-то вроде динамического массива на С++, вы обычно используете std::vector
, и в этом случае есть время выполнения, но стоимость крайне незначительна - O (1). Разница в скорости между sizeof
и some_vector.size()
редко актуальна. Основной из них состоит в том, что поскольку size()
не является константой, может быть некоторая потерянная возможность для оптимизации - например, N/sizeof(short)
обычно оптимизируется на сдвиг вправо вместо фактического деления, поскольку sizeof(short)
является мощность 2. Поскольку компилятор обычно не знает, что whatever.size()
имеет мощность 2, он должен использовать фактическое деление в этом случае. В то же время большинство процессоров оптимизируют деление на мощность 2, поэтому разница остается очень маленькой.
Изменить (поскольку вопрос был перезаписан как C): C (начиная с C99) предоставляет как массивы переменной длины (VLAs), так и члены гибкого массива (FAM). Для массива переменной длины sizeof
выполняет оценку своего параметра, поэтому существует минимальная стоимость выполнения - примерно эквивалентная std::vector::size()
в С++. Для всех других типов (включая struct
, которые включают в себя гибкие элементы массива), sizeof
не оценивает свой операнд, поэтому нет времени выполнения (так же, как в С++).
Для struct
с гибким элементом массива: "размер структуры должен быть равен смещению последнего элемента в противном случае идентичной структуры, которая заменяет элемент гибкого массива массивом неопределенной длины". (C99, §6.7.2.1/16).
sizeof
оценивает размер типа во время компиляции (оценивая только тип выражения), поэтому он не имеет затрат времени исполнения (он точно так же, как если бы вы помещали туда константу).
Так как динамический массив упоминается указателем, sizeof
будет указывать размер указателя. В общем, вы должны вручную отслеживать "реальный" размер динамических массивов, нет никакого способа узнать его из распределителя.
sizeof
- это вызов времени компиляции. Он может работать только на вещах, которые известны во время компиляции. Ваш компилятор определит размер структуры и заменит числовую константу.
sizeof
работает только во время компиляции. Динамический массив будет использовать указатель на динамически выделенную память, которая не будет включена в результат. Вы получите размер указателя и служебной информации (длина массива и т.д.).
Существует нулевая стоимость исполнения. В случае динамически распределенной памяти sizeof задает размер объекта статического указателя, а не динамически выделенной памяти.