Вопрос

Я сделал простую программу и собрал ее с 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

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

Спасибо.

Это было полезно?

Решение

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

Это описано в §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 rvalue of type char, signed char, unsigned char, short int, или же unsigned short intможет быть преобразован в RVALUE типа int если int может представлять все значения типа источника; В противном случае источник RVALUE может быть преобразован в RVALUE типа unsigned int.

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

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

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

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

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

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

Другие советы

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

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

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

Эти ссылки могут быть полезными - вики а также SecureCoding

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top