c++ integer integer-overflow integer-promotion

c++ - La adición de dos caracteres produce int



integer integer-overflow (3)

Cuando realiza una operación aritmética en el tipo de caracteres, el resultado que devuelve es de tipo int .

Mira esto:

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;

Salida:

1
4
4
4
4

Demostración en ideone: http://www.ideone.com/jNTMm

Hice un programa simple y lo compilé con GCC 4.4 / 4.5 de la siguiente manera:

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

g ++ -c -Wconversion a.cpp

Y tengo lo siguiente:

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

La misma advertencia que tengo para el siguiente código:

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

¿Podría alguien explicarme por qué la adición de dos caracteres (o dos cortos sin signo) produce int? ¿Es un error del compilador o es compatible?

Gracias.


Lo que está viendo es el resultado de las llamadas "conversiones aritméticas habituales" que se producen durante las expresiones aritméticas, particularmente aquellas que son de naturaleza binaria (tome dos argumentos).

Esto se describe en §5 / 9:

Muchos operadores binarios que esperan operandos de tipo aritmético o de enumeración causan conversiones y producen tipos de resultados de forma similar. El propósito es producir un tipo común, que también es el tipo del resultado. Este patrón se denomina conversiones aritméticas habituales , que se definen de la siguiente manera:

- Si cualquiera de los dos operandos es del tipo long double , el otro se convertirá a long double .
- De lo contrario, si cualquiera de los dos operandos es double , el otro se convertirá en double .
- De lo contrario, si cualquiera de los operandos es float , el otro se convertirá en float .
- De lo contrario, las promociones integrales (4.5) se realizarán en ambos operandos. 54)
- Entonces, si cualquiera de los operandos tiene un unsigned long el otro se convertirá a unsigned long .
- De lo contrario, si un operando es un long int y el otro unsigned int , entonces si un long int puede representar todos los valores de un unsigned int , el unsigned int se convertirá en un long int ; de lo contrario, ambos operandos se convertirán a unsigned long int .
- De lo contrario, si el operando es long , el otro se convertirá en long .
- De lo contrario, si ninguno de los operandos está unsigned , el otro se convertirá en unsigned .

[Nota: de lo contrario, el único caso restante es que ambos operandos son int ]

Las promociones aludidas en §4.5 son:

1 Un rvalue de tipo char , signed char , unsigned char , short int o unsigned short int se puede convertir a un rvalue de tipo int si int puede representar todos los valores del tipo de fuente; de lo contrario, el valor de origen r se puede convertir a un valor r de tipo unsigned int .

2 Un valor de tipo de tipo wchar_t (3.9.1) o un tipo de enumeración (7.2) se puede convertir a un valor de r del primero de los siguientes tipos que puede representar todos los valores de su tipo subyacente: int , unsigned int , long o unsigned long .

3 Un valor de r para un campo de bit integral (9.6) se puede convertir a un valor r de tipo int si int puede representar todos los valores del campo de bit; de lo contrario, se puede convertir a unsigned int si unsigned int puede representar todos los valores del bit-field. Si el campo de bit es aún más grande, no se aplica ninguna promoción integral. Si el campo de bit tiene un tipo enumerado, se trata como cualquier otro valor de ese tipo para fines de promoción.

4 Un rvalue de tipo bool se puede convertir a un rvalue de tipo int , con false convierte en cero y true convierte en one .

5 Estas conversiones se llaman promociones integrales.

Desde aquí, las secciones como " Operadores multiplicativos " u " Operadores aditivos " tienen la frase: " Se realizan las conversiones aritméticas habituales ... " para especificar el tipo de expresión.

En otras palabras, cuando se hace aritmética integral, el tipo se determina con las categorías anteriores. En su caso, la promoción está cubierta por §4.5 / 1 y el tipo de expresiones son int .


cuando agrega estos dos caracteres entre sí, primero se promocionan a int.

El resultado de una adición es un valor r que se promueve implícitamente para escribir int si es necesario, y si un int puede contener el valor resultante. Esto es cierto en cualquier plataforma donde sizeof (int)> sizeof (char). Pero ten cuidado con el hecho de que Char puede ser tratado como char firmado por tu compilador.

Estos enlaces pueden ser de ayuda adicional: wiki y securecoding