Тип всего выражения

182
14 августа 2017, 11:06

Недавно написал такую функцию:

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.

Собственно вопрос: почему так? В выражении участвовали знаковые и беззнаковые переменные, почему компилятор отдал предпочтение беззнаковым?

Answer 1

Так как 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, т.е. знаковый тип.

READ ALSO
config.h: No such file or directory

config.h: No such file or directory

Привет! Пытаюсь скомпилять это чтоб создать нагрузку на свой rsyslog для тестирования сжатияНо эта зараза ни в какую не хочет компиляться, ругается...

247
Текущая директория плюс строка в PTCHAR [требует правки]

Текущая директория плюс строка в PTCHAR [требует правки]

Есть функция, принимающая параметр PTCHAR path, этим параметром мне нужно передать текущую директорию (откуда запущен exe), склеенную со статичной...

289
Запись и чтение данных в SQLite3 на с++

Запись и чтение данных в SQLite3 на с++

Добрый день! Как правильно записать данные в sqlite, и соответственно считать их на с++? Данные представляют собой несколько переменных разных...

202
Объединение нескольких send&#39;ов в один recv

Объединение нескольких send'ов в один recv

Может ли случиться так, что все данные, посланные несколькими операциями send(), на хосте назначения будут считаны всего одним вызовом recv()?

215