Подтвердить что ты не робот

Добавление двух символов создает int

Я сделал простую программу и скомпилировал ее с помощью GCC 4.4/4.5 следующим образом:

int main ()
{
  char u = 10;
  char x = 'x';
  char i = u + x;

  return 0;
}

g++ -c -Wconversion a.cpp

И у меня есть следующее:

a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘char’ from ‘int’ may alter its value

То же предупреждение, которое я получил для следующего кода:

  unsigned short u = 10;
  unsigned short x = 0;
  unsigned short i = u + x;

a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘short unsigned int’ from ‘int’ may alter its value

Может ли кто-нибудь объяснить мне, почему добавление двух символов (или двух неподписанных шорт) вызывает int? Это ошибка компилятора или стандартная совместимость?

Спасибо.

4b9b3361

Ответ 1

То, что вы видите, является результатом так называемых "обычных арифметических преобразований", которые возникают во время арифметических выражений, в частности, двоичных по природе (принимают два аргумента).

Это описано в § 5/9:

Многие двоичные операторы, которые ожидают операнды арифметики или типа перечисления, вызывают конверсии и дают аналогичные результаты. Цель состоит в том, чтобы дать общий тип, который также является типом результата. Этот шаблон называется обычными арифметическими преобразованиями, которые определяются следующим образом:

- Если один из операндов имеет тип long double, другой должен быть преобразован в long double.
- В противном случае, если любой операнд double, другой должен быть преобразован в double.
- В противном случае, если любой операнд float, другой должен быть преобразован в float.
- В противном случае интегральные акции (4.5) должны выполняться на обоих операндах. 54)
- Тогда, если любой из операндов unsigned long, другой должен быть преобразован в unsigned long.
- В противном случае, если один операнд равен long int, а другой unsigned int, то если a long int может представлять все значения a unsigned int, unsigned int преобразуется в long int; в противном случае оба операнда должны быть преобразованы в unsigned long int.
- В противном случае, если любой операнд long, другой должен быть преобразован в long.
- В противном случае, если любой операнд unsigned, другой должен быть преобразован в unsigned.

[Примечание: в противном случае единственным оставшимся случаем является то, что оба операнда int]

Акциями, упомянутыми в п. 4.5, являются:

1 Значение типа char, signed char, unsigned char, short int или unsigned short int может быть преобразовано в rvalue типа int, если int может представлять все значения Тип источника; в противном случае исходное значение rvalue может быть преобразовано в rvalue типа unsigned int.

2 rvalue типа wchar_t (3.9.1) или тип перечисления (7.2) можно преобразовать в rvalue первого из следующих типов, который может представлять все значения его базового типа: int, unsigned int, long или unsigned long.

3 Значение для целочисленного битового поля (9.6) может быть преобразовано в rvalue типа int, если int может представлять все значения битового поля; в противном случае его можно преобразовать в unsigned int, если unsigned int может представлять все значения битового поля. Если бит-поле еще больше, к нему не применяется целая реклама. Если бит-поле имеет нумерованный тип, оно рассматривается как любое другое значение этого типа для целей продвижения по службе.

4 Значение типа bool может быть преобразовано в rvalue типа int, при этом false становится равным нулю, а true становится one.

5 Эти преобразования называются интегральными акциями.

Здесь разделы, такие как " Мультипликативные операторы" или " Аддитивные операторы", имеют фразу: "Обычные арифметические преобразования выполняются..." для указания тип выражения.

Другими словами, когда вы выполняете интегральную арифметику, тип определяется с помощью категорий выше. В вашем случае поощрение распространяется на §4.5/1, а тип выражений - int.

Ответ 2

Когда вы выполняете какую-либо арифметическую операцию в типе char, возвращаемый результат имеет тип int.

Смотрите это:

char c = 'A';
cout << sizeof(c) << endl;
cout << sizeof(+c) << endl;
cout << sizeof(-c) << endl;
cout << sizeof(c-c) << endl;
cout << sizeof(c+c) << endl;

Вывод:

1
4
4
4
4

Демонстрация на идеоне: http://www.ideone.com/jNTMm

Ответ 3

когда вы добавляете эти два символа друг к другу, они сначала повышаются до int.

Результат добавления - это значение, которое неявно продвигается до введите int, если необходимо, и если int может содержать результирующее значение. Это верно на любой платформе, где sizeof (int) > sizeof (char). Но остерегайтесь того, что char может считаться подписанным char ваш компилятор.

Эти ссылки могут быть полезны - wiki и securecoding