Дает ли" int size = 10; " постоянное выражение?

следующий код компилируется под gcc 4.8 и Clang 3.2:

int main()
{
  int size = 10;
  int arr[size];
}

8.3.4 / 1 стандарта C++ говорит, что размер массива должен быть интегральным постоянным выражением, которое size не представляется. Это ошибка в обоих компиляторах, или я что-то упускаю?

последний VC++ CTP отклоняет код с этим интересным сообщением:

error C2466: cannot allocate an array of constant size 0

интересная часть заключается в том, как он, кажется, думает, что size равна нулю. Но по крайней мере он отвергает код. Разве gcc и Clang не должны делать то же самое?

1 ответов


это массивы переменной длины или вла что это C99 но gcc и лязгом поддержка его в качестве расширения в 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 и говорит:

выражение интегральной константы-это выражение типа перечисления integral или unscoped, неявно преобразованное в prvalue, где преобразованное выражение является основной константой выражение. [...]

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

в этом случае после инициализации 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) такие массивы тем не менее являются полными типами. Если размер является целочисленным постоянным выражением, а тип элемента имеет известный постоянный размер, то тип массива не является типом массива переменной длины;в противном случае тип массива является типом массива переменной длины.