Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

GCC и Varable-Length Arrays

Anna | 24.06.2014 | нет комментариев

Одногруппник прислал C -код с какой-то оплошностью и итог компилятора по этому поводу. Но больше каждого меня поразила не его задача, а то, что в коде создавался на стеке массив с незнакомой на этапе компиляции длиной. Помнится, в начале постижения языка столкнулся с этим и уяснил, что так делать невозможно. Необычно, но других ошибок компилятор одногруппника не выдал…

Где-то читал, что дальнейший Эталон C 14, допустимо, дозволит исполнять такой трюк. Но подлинный говорит, что размер массива должен быть constant expression. Это еще раз сокращает совместимость с C99, где VLAs давным-давно доступны.

Я использую GCC 4.8.1, следственно на нем решил проверить:

void foo( int n)
{
    int array[n];
}

Компилятор с опцией -pedantic Добросовестно выдал:

warning: ISO C forbids variable length array ‘array’.

На самом деле, VLAs для C в gcc являются растяжением.

Самое главное, что оператор sizeof считает размер массивов переменной длины в рантайме, а не в компайлтайме. Следственно, скажем, мы не сумеем инстанцировать образец с параметром-нетипом с поддержкой такого sizeof( vla ):

template <int p>
class A
{
};
void foo(int length)
{
    int const_lenght_array[7];
    int variable_length_array[length];
    A<sizeof(const_lenght_array)> a1; //OK
    A<sizeof(variable_length_array)> a2; //ERROR
}

Сообщение компилятора об ошибке приятно отвечает, каким образом вычисляется в рантайме размер массива:

error: ‘(unsigned int)((((sizetype)(((ssizetype)length) -1)) 1u) * 4u)’ is not a constant expression

Также дозволено применять указатели на массивы переменной длины и typedef:

int (*p)[length] = &variable_length_array;
typedef int variable_int_array_t [length];

Больше каждого сказанного, GNU-растяжение разрешает создавать массивы переменной длины массивов переменной длины, что не дозволено даже для new, где только верхний ярус может иметь переменную длину:

void bar(int a, int b)
{
    int auto_array[a][b]; //OK
    int (*dynamic_array)[b] = new int[a][b]; //ERROR 
}

Отличная новость, что в C 14 будут введены VLAs, только во многом не совместимые c VLAs данного растяжения и C99. По крайней мере, sizeof и typedef/using(c 11) для них будет ill-formed. Это дозволит не наступить на грабли, ждать от sizeof только компайлтайм-поведения. Вот ссылка на патч для gcc.

Я знаю, что многие считают, что VLAs в C становятся непотребными: для сходственных целей существует vector, и никому не увлекательно, где в реальности выдается память под элементы. Тем не менее, целью статьи ставилось показать такую вероятность у gcc, Дабы позднее не поразиться.
В завершение, предложение о VLAs в open-std.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB