Ошибка компилятора? g++ допускает статические массивы переменного -размера, если только функция не является шаблонной

Код ниже демонстрирует поведение gcc 4.6.2, которое я не могу объяснить. Первая функция объявляет статический массив типа vec _t, где vec _t является псевдонимом typedef для unsigned char. Вторая функция идентична, за исключением того, что тип вектора _t является параметром шаблона. Вторая функция не компилируется с диагностикой «ошибка :размер хранилища ‘bitVec’ не является постоянным».

#include <limits>

void bitvec_func()
{
    const std::size_t       nbits = 1e7;
    typedef unsigned char   vec_t;
    const std::size_t       WLEN  = std::numeric_limits<vec_t>::digits;
    const std::size_t       VSIZ  = nbits/WLEN+1;
    static vec_t            bitVec[nbits/VSIZ];    // Compiles fine
}

template <typename T>
void bitvec_func()
{
    const std::size_t       nbits = 1e7;
    typedef T               vec_t;
    const std::size_t       WLEN  = std::numeric_limits<vec_t>::digits;
    const std::size_t       VSIZ  = nbits/WLEN+1;
    static vec_t            bitVec[nbits/VSIZ];    // "error: storage size of ‘bitVec’ isn’t constant"
}

void flarf()
{
    bitvec_func();
    bitvec_func<unsigned char>();
}

Мне кажется, что создание экземпляра шаблона с аргументом должно привести к тому, что компилятор сгенерирует тот же код, что и первая функция. Может ли кто-нибудь предложить какое-либо понимание того, почему это не так?

[Дополнение :вторая функция будет компилироваться с "-std=c++0x" или "-std=gnu++0x", но мне все равно хотелось бы чтобы понять, как/если это неправильно в соответствии с более ранними языковыми определениями.]

Расчетное время прибытия:
Вторая функция будет скомпилирована, если инициализатор для nbits будет изменен:

const std::size_t       nbits = 1e7;              // Error
const std::size_t       nbits = (std::size_t)1e7; // Okay
const std::size_t       nbits = 10000000.0;       // Error
const std::size_t       nbits = 10000000;         // Okay

Другими словами, кажется, что если nbitsинициализировать выражением целочисленного типа,тогда nbitsтрактуется как константа в определении bitVec. Если nbitsвместо этого инициализируется выражением с плавающей запятой -, компилятор больше не видит его как константу в выражении для размерности bitVec, и компиляция завершится ошибкой.

Мне гораздо менее удобно называть "ошибку компилятора" в C++, чем в C, но я не могу придумать никакой другой причины, по которой приведенные выше 4 случая не были бы семантически идентичными. Кто-нибудь еще хочет высказать мнение?

6
задан John Auld 7 June 2012 в 02:36
поделиться