Работает ли sizeof во время компиляции? - PullRequest
3 голосов
/ 24 августа 2011

Я запустил этот пример программы.

const int x = 5;
int main(int argc, char** argv)
{
    int x[x];

    int y = sizeof(x) / sizeof(int);

    return 0;
}

Значение y равно 5.

Но как это возможно? Потому что, когда я отлаживал, значение x было 5, поэтому размер x равен 4, а размер int равен 4. И значение y должно было отличаться.

Что мне не хватает?

Ответы [ 4 ]

7 голосов
/ 24 августа 2011

sizeof(x) относится к массиву, который имеет 5 элементов типа int.Отсюда вывод.

Код было бы намного проще понять, если бы вы не перегружали имя x.

Технически, что у вас есть, это массив переменной длины, VLA,Это потому, что C const на самом деле означает только чтение и должен быть оценен во время выполнения.Следовательно, sizeof, в этом случае, оценивается во время выполнения.

Если бы вы использовали литерал вместо размера вашего массива, то есть int x[5];, тогда sizeof было бы оценено во время компиляции.

Если бы код был скомпилирован как C ++, тогда const был бы истинным const и поэтому был бы доступен для оценки во время компиляции.

4 голосов
/ 24 августа 2011

У вас здесь скрывается переменная.Ваш код примерно эквивалентен:

const int x = 5;
int main(int argc, char** argv)
{
    int x2[x];

    int y = sizeof(x2) / sizeof(int);

    return 0;
}

Тогда он будет понятнее: sizeof(x)==4, x==5, sizeof(x2)==20.

0 голосов
/ 24 августа 2011

Поскольку int x равно const, это массив фиксированного размера.Sizeof вычисляется во время компиляции.

x состоит из пяти элементов, как ясно показывает определение.Его размер равен 5 * sizeof (int).

Это GCC, я использую printf для вывода значения y:

subl    $48, %esp
movl    $5, 4(%esp)`

И выделенное пространство, и значение yСоставлено как константы.

Также из стандарта:

If the size is an integer constant expression and the element type has
a known constant size, the array type is not a variable length array type [...]
0 голосов
/ 24 августа 2011

x имеет тип int [5]. Следовательно, размер 5 * sizeof (int). sizeof - это оператор, а не функция или макрос.

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

...