Добавление двух символов производит int - PullRequest
21 голосов
/ 27 января 2011

Я сделал простую программу и скомпилировал ее с 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?Это ошибка компилятора или она соответствует стандарту?

Спасибо.

Ответы [ 3 ]

24 голосов
/ 27 января 2011

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

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

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

- Если один из операндов имеет тип long double, другой должен быть преобразован в long double.
- В противном случае, если один из операндов равен double, другой должен быть преобразован в double.
- В противном случае, если один из операндов равен float, другой должен быть преобразован в float.
- В противном случае интегральные преобразования (4.5) должны выполняться для обоих операндов. 54)
- Затем, если один из операндов равен unsigned long, другой должен быть преобразован в unsigned long.
- В противном случае, если один операнд является long int, а другой unsigned int, то, если long int может представлять все значения 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 может быть преобразовано в значение типа int, если int может представлять все значения Тип источника; в противном случае исходное значение r может быть преобразовано в значение типа unsigned int.

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

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

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

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

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

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

5 голосов
/ 27 января 2011

Когда вы выполняете любую арифметическую операцию с типом 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

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

3 голосов
/ 27 января 2011

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

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

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

...