Ошибка для массива отрицательного размера

Почему бы мне не получить ошибку, пытающуюся создать массив с отрицательным размером?

#include <array>

int main()
{
    std::array<int, -1> arr;
}

С -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC я не получаю ошибки. Это предполагаемое поведение?

Ответ 1

Нет, это не законно. Нет ничего о спецификации std::array, которая явно предотвращает это, но это незаконно из-за сужения конверсий.

§14.3.2/5:

Для нестандартного шаблона-параметра интегрального или перечисляемого типа преобразования разрешенные в преобразованном постоянном выражении (5.19).

§5.19/3:

Преобразованное константное выражение типа T является литеральным постоянным выражением, неявно преобразованный в тип T, где неявное преобразование (если оно есть) разрешено в литеральном постоянном выражении и неявной последовательности преобразования содержит только определенные пользователем преобразования, преобразования lvalue-to-rvalue (4.1), интегральные поощрения (4.5) и интегральные преобразования (4.7), кроме сужения преобразования (8.5.4)

Единственный способ заставить GCC жаловаться - включить -Wsign-conversion. Это известная ошибка, и они не сделали никакого движения, чтобы исправить ее.

В Clang вы получите ожидаемое сообщение об ошибке:

error: non-type template argument evaluates to -1, which cannot be 
narrowed to type 'std::size_t' (aka 'unsigned long') [-Wc++11-narrowing]
    std::array<int, -1> arr;

Ответ 2

Тип std::array:

template< 
    class T, 
    std::size_t N 
> struct array;

Когда вы инициализируете второй параметр шаблона с помощью -1, он неявно преобразуется в очень большое значение, поскольку std::size_t is unsigned (что является незаконным в С++, как указано другой ответ, и он должен быть диагностирован).

Другая возможность заключается в том, что ваш arr оптимизирован. Вы можете подтвердить это, добавив флаг -fdump-tree-optimized в командную строку gcc.

Если вы уверены, что arr не оптимизирован, я надеюсь, что вы получите следующее предупреждение:

prog.cpp:5:25: error: size of variable 'arr' is too large
     std::array<int, -1> arr;