23

Вопрос по c – Как sizeof (массив) работает во время выполнения?

Я читал, что оператор sizeof в C интерпретируется во время компиляции, и поскольку во время компиляции компилятор знает размер массива и его тип, sizeof способен вычислить количество байтов, занимаемых массивом. Но как sizeof работает для следующего кода:

 #include<stdio.h>
 #include<string.h>
 int main()
 {
    int n;
    scanf("%d",&n);
    int a[n];
    int s=sizeof(a);
    printf("%d",s);
    return 0;
 }

Здесь размер массива не известен во время компиляции, тогда как он работает правильно?

@ M & # x414; & # x393; & # x393; & # x411; & # x414; LL: Ваш возможный дубликат имеет дело с другой ситуацией (<code>malloc()</code>, а не VLA, массив переменной длины).

Apr 09, 2012, 7:07 PMот

@ M & # x414; & # x393; & # x393; & # x411; & # x414; LL Нет, речь идет о<code>malloc</code>Вещи, а не о VLA.

Apr 09, 2012, 7:07 PMот

Массивы переменной длины являются исключением, для них<code>sizeof</code> оценивается во время выполнения, а не во время компиляции.

Apr 09, 2012, 7:06 PMот

возможный дубликат<a href="http://stackoverflow.com/questions/2731500/using-sizeof-with-a-dynamically-allocated-array">Using sizeof with a dynamically allocated array</a>

Apr 09, 2012, 7:06 PMот

6ответов

2

В таком случае,sizeof() оценивается во время выполнения. Компилятор, потому что он знает, что размерa основан на значенииn во время объявления массива генерирует код для использования соответствующего значенияn вернуть разумное значение дляsizeof().

В C99 не все виды использованияsizeof() может быть полностью оценена во время компиляции и сведена к постоянной времени выполнения.

7

Из стандарта C99:

6.5.3.4

sizeof Оператор возвращает размер (в байтах) своего операнда, который может быть выражение или заключенное в скобки имя типа. Размер определяется по типу операнд. Результатом является целое число.If the type of the operand is a variable length array type, the operand is evaluated; в противном случае, операнд не оценивается, а результат целочисленная константа.

14

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

Оптимизаторы высокого уровня gcc 4.6.3 преобразуют код, который вы показали в

scanf ("%d", &n);
t12 = (long unsigned int) n;
t13 = t12 * 4;
__builtin_alloca (t13);
t16 = (unsigned int) t12;
t17 = t16 * 4;
s18 = (int) t17;
printf ("%d", s18);

Это объясняет, что происходит под капотом? (Не откладывайте на глупое количество временных переменных - это артефакт программы, находящейся встатическое одиночное назначение Форма в точке, где я попросил дамп промежуточного кода.)

1

Несмотря на погодуsizeof вычисляется во время компиляции или во время выполнения (или, если говорить более формально, является ли его результат целочисленным константным выражением), результатsizeof основывается исключительно наtype of its argument а не какие-либо скрытые данные, сопровождающие сам массив переменной длины. Конечно когдаsizeof применяется к переменно-измененному типу, сгенерированная программа должна где-то отслеживать этот размер. Но он может просто пересчитать его, если выражение было достаточно простым, и переменные, из которых оно изначально получило длину, не могли измениться. Или, он может хранить размер типа где-то (по существу, в скрытой локальной переменной), но это не будет связано с объектом VLA каким-либо наблюдаемым способом (например, если вы передаете указатель на первый элемент VLA для другой функции этот указатель не может быть использован для восстановления длины VLA).

27

sizeof всегда вычисляется во время компиляции в C89. Поскольку C99 и массивы переменной длины, он вычисляется во время выполнения, когда массив переменной длины является частью выражения вsizeof операнд.

То же самое для оценкиsizeof операнд: он не оценивается в C89, но в C99, если операнд имеет тип массива переменной длины, он оценивается. Например:

int n = 5;
sizeof (int [n++]); 

// n is now 6
2

I have read that sizeof operator in C is interpreted at compile time

sizeof определяется во время компиляции во всех случаях, кроме VLA. Для VLA,sizeof оценивается во время выполнения.

RelatedQuestions