Следующий код компилируется в gcc 4.8 и Clang 3.2:
int main()
{
int size = 10;
int arr[size];
}
8.3.4 / 1 Стандарта C ++ говорит, что размер массива должен быть целочисленным константным выражением, которое size
не похоже. Это ошибка в обоих компиляторах или я что-то упустил?
Последний CTP VC ++ отклоняет код с этим интересным сообщением:
error C2466: cannot allocate an array of constant size 0
Интересно то, как кажется, что size
это ноль. Но по крайней мере это отклоняет код. Разве gcc и Clang не должны делать то же самое?
Это массивы переменной длины или же VLA который является C99 особенность, но НКУ а также лязг поддержать его как расширение в C ++ в то время как Visual Studio не. Так Visual Studio
в этом случае придерживается стандарта и является технически правильным. Не сказать, что расширения плохие, Ядро Linux зависит от многих расширений gcc, поэтому они могут быть полезны в определенных контекстах.
Если вы добавите -pedantic
пометить оба gcc
а также clang
предупредит вас об этом, например gcc
говорит (увидеть это в прямом эфире):
warning: ISO C++ forbids variable length array 'arr' [-Wvla]
int arr[size];
^
С использованием -pedantic-errors
флаг сделает это ошибкой. Вы можете прочитать больше о расширениях в этих документах Языковые стандарты, поддерживаемые GCC а также раздел совместимости языков clangs.
Обновить
проект стандарта C ++ охватывает то, что является интегральное постоянное выражение в разделе 5.19
Постоянные выражения параграф 3 и говорит:
Выражение с интегральной константой — это выражение типа перечисления с целым числом или с незаданной областью, неявно преобразуемое в значение типа prvalue, где преобразованное выражение является выражением основной константы. […]
Из прочтения этого материала не совсем понятно, какие есть все Рекомендации по кодированию для интегральных константных выражений делает большую работу из этого.
В этом случае, так как вы инициализируете size
с буквальный с помощью Const было бы достаточно, чтобы сделать это интегральное постоянное выражение (увидеть [Expr.const] p2.9.1), а также вернуть код в стандартное состояние C ++:
const int size = 10;
с помощью constexpr будет работать тоже
constexpr int size = 10;
Это, вероятно, помогло бы прочитать Разница между constexpr
а также const
.
Для справки эквивалентный раздел 8.3.4
параграф 1 в Проект стандарта C99 будет раздел 6.7.5.2
Массив объявлений параграф 4 который говорит (акцент мой):
Если размер отсутствует, тип массива является неполным типом. Если размер равен *, а не является выражением, тип массива является типом массива переменной длины неопределенного размера, который может использоваться только в объявлениях с областью прототипа функции;124) такие массивы, тем не менее, являются полными типами. Если размер является целочисленным константным выражением и тип элемента имеет известный постоянный размер, тип массива не является типом массива переменной длины; в противном случае тип массива является типом массива переменной длины.
Других решений пока нет …