Почему сумма unsigned char имеет тип int? [дубликат]

109
02 января 2021, 03:30
На этот вопрос уже даны ответы здесь:
Неявное приведение типов данных (2 ответа)
Язык C, странное поведение при сравнении знаковых и беззнаковых (2 ответа)
Закрыт 1 год назад.

В следующем примере:

#include <iostream>
#include <typeinfo>
int main()
{
    unsigned char a, b, c;
    a = 100;
    b = 100;
    c = 100;
    int x = (a + b + c);
    std::cout << "typeid(a + b + c) = " << typeid(a + b + c).name() << std::endl;
    std::cout << "x                 = " << x << std::endl;
    std::cout << "a + b + c         = " << a + b + c << std::endl;
    return 0;
}

получаем вывод:

typeid(a + b + c) = i
x                 = 300
a + b + c         = 300

Как видим, сумма unsigned char'ов не переполнилась, а тип суммы оказывается int'ом. Это для меня странно, мне казалось, стандартом гарантировано переполнение беззнаковых типов с взятием остатка от деления на максимальное представимое число, то есть в примере выше x должен был бы оказаться равен 300 % 256 = 44 .

В чём моя ошибка? Желательно со ссылкой на стандарт или cppreference.

PS. Ссылка для экспериментов: http://cpp.sh/7t35b

Answer 1

The following may be used in an expression wherever an int or unsigned int may be used:

— An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.

— A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions.

Перевод:

Cледующее может быть использовано в выражении везде, где может использоваться int или unsigned int:

  • Объект или выражение с целочисленным типом (кроме int или unsigned int), чей ранг целочисленного преобразования меньше или равен рангу int и unsigned int.

  • Битовое поле типа _Bool, int, sign int или unsigned int.

Если int может представлять все значения исходного типа (как ограничено шириной для битового поля), значение преобразуется в int; в противном случае он конвертируется в беззнаковое целое. Они называются целочисленными продвижениями. 58) Все остальные типы не изменяются целочисленными продвижениями.

В вашем примере при запуске функции сложения, любой аргумент типа char автоматически преобразуется в int.

movb    $100, 13(%rsp)
movb    $100, 14(%rsp)
movb    $100, 15(%rsp)
movzbl  13(%rsp), %ebx
movzbl  14(%rsp), %edx
movzbl  15(%rsp), %eax
addl    %edx, %ebx
addl    %eax, %ebx

Компилятор хранит данные размером в один байт, а сложение выполняет как с целочисленными аргументами.

READ ALSO
Qt/C++ Как &ldquo;перевернуть&rdquo; строку по вертикали?

Qt/C++ Как “перевернуть” строку по вертикали?

Делаю график на QtНужно подписать координатную ось ОY

96
Как создать новость в категории DLE?

Как создать новость в категории DLE?

Как создать новость в категории DLE? я создал категорию Партнеры, но не могу туда добавить новость, добавил код в about-navtpl

101
Эффект-прозрачности

Эффект-прозрачности

Не могу никак отстилизовать последнего кота

99
Как вставить эти картинки background?

Как вставить эти картинки background?

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

139