Странный тип вычета - PullRequest
6 голосов
/ 03 мая 2020

Сегодня я увидел действительно странный вывод типа. Вот код:

unsigned int y = 15;
int k = 5;
auto t = k - y / 2;

Поскольку k равно int, я предположил, что тип t также должен быть int. Но, к моему удивлению, это тип unsigned int. Я не могу найти, почему тип выводится как unsigned int. Есть идеи почему?

1 Ответ

6 голосов
/ 03 мая 2020

Из-за обычных арифметических преобразований c, если два операнда имеют одинаковый ранг преобразования, а один из операндов имеет тип целого без знака, тогда тип выражения имеет тот же тип целого числа без знака.

Из Стандарт C ++ 17 (5 выражений, стр. # 10)

- В противном случае, если операнд с целочисленным типом без знака имеет ранг, больший или равный рангу типа другого операнда, операнд с целым типом со знаком должен быть преобразован в тип операнда с целым типом без знака.

Обратите внимание, что ранг преобразования типа unsigned int равен рангу типа int (signed int). Из стандарта C ++ 17 (4.13. Целочисленный ранг преобразования, стр. # 1)

- ранг любого целого типа без знака должен равняться рангу соответствующего целочисленного типа со знаком

Более интересным примером является следующее. Предположим, что есть два объявления

unsigned int x = 0;
long y = 0;

, а ширина обоих типов одинакова и равна, например, 4 байтов. Как известно, ранг типа long больше, чем ранг типа unsigned int. Возникает вопрос, какой идентификатор типа выражения

x + y

Тип выражения unsigned long .:)

Вот демонстрационная программа, но вместо типов long и unsigned int используются типы long long и unsigned long.

#include <iostream>
#include <iomanip>
#include <type_traits>

int main() 
{
    unsigned long int x = 0;
    long long int y = 0;

    std::cout << "sizeof( unsigned long ) = " 
              << sizeof( unsigned long )
              << '\n';

    std::cout << "sizeof( long long ) = " 
              << sizeof( long long )
              << '\n';

    std::cout << std::boolalpha 
              << std::is_same<unsigned long long, decltype( x + y )>::value
              << '\n';

    return 0;
}

Выход программы:

sizeof( unsigned long ) = 8
sizeof( long long ) = 8
true

Это тип выражения x + y unsigned long long хотя ни один из операндов выражения не имеет этот тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...