Недавно написал такую функцию:
template
capacity - вместимость какого-то буфера
size - количество занятых байт.
Функция проверяет достаточно ли в буфере места для объекта типа T. Проблема оказалось в том, что результат выражения capacity - size - sizeof(T) получался unsigned из за sizeof. Таким образом функция всегда возвращала true.
Собственно вопрос: почему так? В выражении участвовали знаковые и беззнаковые переменные, почему компилятор отдал предпочтение беззнаковым?
Ответ
Так как size_t является беззнаковым типом, а int знаковым, и ранг size_t не меньше ранга int, то из текущего черновика стандарта п.8/11 следует, что в данном случае будет выполнено целочисленное продвижение (integral promotion) и результатом выражения стенет беззнаковый тип
Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.
Небольшой пример для демонстрации
#include
int main()
{
int i = 100;
size_t st = 42;
unsigned short us = 42;
std::cout << st - i << "
"; // size_t
std::cout << us - i << "
"; // int
}
18446744073709551558
-58
В первом случае выражение имеет тип size_t, беззнаковый, т.е. ситуация аналогичная описанной в вопросе. Во втором случае - ранг unsigned short меньше, чем ранг int и результат - int, т.е. знаковый тип.
Комментариев нет:
Отправить комментарий