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á along double
.
- De lo contrario, si cualquiera de los dos operandos esdouble
, el otro se convertirá endouble
.
- De lo contrario, si cualquiera de los operandos esfloat
, el otro se convertirá enfloat
.
- De lo contrario, las promociones integrales (4.5) se realizarán en ambos operandos. 54)
- Entonces, si cualquiera de los operandos tiene ununsigned long
el otro se convertirá aunsigned long
.
- De lo contrario, si un operando es unlong int
y el otrounsigned int
, entonces si unlong int
puede representar todos los valores de ununsigned int
, elunsigned int
se convertirá en unlong int
; de lo contrario, ambos operandos se convertirán aunsigned long int
.
- De lo contrario, si el operando eslong
, el otro se convertirá enlong
.
- De lo contrario, si ninguno de los operandos estáunsigned
, el otro se convertirá enunsigned
.[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
ounsigned short int
se puede convertir a un rvalue de tipoint
siint
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 tipounsigned 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
ounsigned long
.3 Un valor de r para un campo de bit integral (9.6) se puede convertir a un valor r de tipo
int
siint
puede representar todos los valores del campo de bit; de lo contrario, se puede convertir aunsigned int
siunsigned 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 tipoint
, confalse
convierte en cero ytrue
convierte enone
.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