Код ниже демонстрирует поведение 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 случая не были бы семантически идентичными. Кто-нибудь еще хочет высказать мнение?