Недавно написал такую функцию:
template<class T>
bool isAvailableSpace(int size, int capacity){
return capacity - size - sizeof(T) >= 0;
}
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 <iostream>
int main()
{
int i = 100;
size_t st = 42;
unsigned short us = 42;
std::cout << st - i << "\n"; // size_t
std::cout << us - i << "\n"; // int
}
18446744073709551558
-58
В первом случае выражение имеет тип size_t
, беззнаковый, т.е. ситуация аналогичная описанной в вопросе. Во втором случае - ранг unsigned short
меньше, чем ранг int
и результат - int
, т.е. знаковый тип.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Привет! Пытаюсь скомпилять это чтоб создать нагрузку на свой rsyslog для тестирования сжатияНо эта зараза ни в какую не хочет компиляться, ругается...
Есть функция, принимающая параметр PTCHAR path, этим параметром мне нужно передать текущую директорию (откуда запущен exe), склеенную со статичной...
Добрый день! Как правильно записать данные в sqlite, и соответственно считать их на с++? Данные представляют собой несколько переменных разных...
Может ли случиться так, что все данные, посланные несколькими операциями send(), на хосте назначения будут считаны всего одним вызовом recv()?