Pregunta

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

¿Alguien podría explicarme por qué la adición de dos caracteres (o dos pantalones cortos sin firmar) produce int? ¿Es un error del compilador o cumple con estándar?

Gracias.

¿Fue útil?

Solución

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

Esto se describe en §5/9:

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

- Si cualquiera de los operando es de tipo long double, el otro se convertirá enlong double.
- De lo contrario, si cualquier operando es double, el otro se convertirá en double.
- De lo contrario, si cualquier operando 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 cualquier operando es unsigned long el otro se convertirá en 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, la unsigned int se convertirá a un long int; de lo contrario, ambos operandos se convertirán en unsigned long int.
- De lo contrario, si cualquier operando es long, el otro se convertirá en long.
- De lo contrario, si cualquier operando es 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 intse puede convertir a un rValue de tipo int si int puede representar todos los valores del tipo de origen; De lo contrario, el rValue de origen se puede convertir en un rValue de tipo unsigned int.

2 un rValue de tipo wchar_t (3.9.1) o un tipo de enumeración (7.2) puede convertirse en un rValue del primero de los siguientes tipos que pueden representar todos los valores de su tipo subyacente: int, unsigned int, long, o unsigned long.

3 Un rValue para un campo de bits integral (9.6) se puede convertir en un rValue de tipo int si int puede representar todos los valores del campo de bits; de lo contrario, se puede convertir a unsigned int si unsigned int puede representar todos los valores del campo de bits. Si el campo de bits es más grande aún, no se aplica una promoción integral. Si el campo de bits 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 convertirse en cero y true convirtiéndose one.

5 Estas conversiones se llaman promociones integrales.

Desde aquí, secciones como "Operadores multiplicativos" o "Operadores aditivos"Todos tienen la frase:"Las conversiones aritméticas habituales se realizan ..."Para especificar el tipo de expresión.

En otras palabras, cuando realiza 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.

Otros consejos

Cuando realiza cualquier operación aritmética en char tipo, el resultado que devuelve es de int escribe.

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;

Producción:

1
4
4
4
4

Demostración en ideona: http://www.ideone.com/jntmm

Cuando agregan estos dos personajes entre sí, primero están siendo promovidos a Int.

El resultado de una adición es un rValue 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 SIMEOF (INT)> SIMEOF (char). Pero tenga cuidado con el hecho de que Char podría ser tratado como firmado por su compilador.

Estos enlaces pueden ser de mayor ayuda - wiki y Securecoding

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top