Рассмотрите следующий код:
template<bool> class StaticAssert;
template<> class StaticAssert<true> {};
StaticAssert< (-1 < sizeof(int)) > xyz1; // Compile error
StaticAssert< (-1 > sizeof(int)) > xyz2; // OK
Почему -1 > sizeof(int)
верный?
-1
продвинут на unsigned(-1)
и затем unsigned(-1) > sizeof(int)
.-1 > sizeof(int)
эквивалентно -1 > size_t(4)
если sizeof (интервал) равняется 4. Если это то, итак, почему -1 > size_t(4)
ложь?Действительно ли этот C++ стандартный совместимый?
Стандарт (ISO 14882) следующим образом объясняет abort -1 > sizeof(int)
Реляционный оператор `>' определен в 5.9 (expr.rel/2)
Обычные арифметические преобразования выполняются для операндов арифметического или перечислительного типа. ...
Обычные арифметические преобразования определены в 5 (expr/9)
... Шаблон называется обычными арифметическими преобразованиями, которые определяются следующим образом:
Интегральное продвижение определено в 4.5 (conv.prom/1)
Значение r типа char, signed char, unsigned char, short int, или unsigned short int может быть преобразовано в r-значение типа int, если int может представлять все значения исходного типа; в противном случае исходное r-значение может быть быть преобразовано в r-значение типа unsigned int.
Результат sizeof определен в 5.3.3 (expr.sizeof/6)
Результатом является константа типа size_t
size_t определен в стандарте C (ISO 9899), который является беззнаковым целым типом.
Поэтому для -1 > sizeof(int)
, > вызывает обычные арифметические преобразования. Обычное арифметическое преобразование конвертирует -1 в unsigned int, потому что int не может представлять все значение size_t
. -1
становится очень большим числом, зависящим от платформы. Поэтому -1 > sizeof(int)
- true
.
Поскольку беззнаковый более сильный, чем подписанный и -1 преобразован в беззнаковое значение с size_t
, на самом деле -1 == 0xFFFFFFFF> 4
Это как это должно работать согласно стандарту C ++
потому что -1 приводится к size_t
, а это беззнаковый тип данных - так что (size_t)-1 == 4294967295
(на 32-битной системе), что определенно больше 4
если вы добавите -Wall
в настройки gcc, например, вы получите предупреждение, что вы сравниваете знаковый и беззнаковый тип данных