2010-02-17 12 views
19

Tengo una consulta acerca de las reglas de promoción de tipos de datos en lenguaje C estándar. El C99 dice que:En una expresión C, donde unsigned int int y firmaron están presentes, el tipo será promovido a qué tipo?

promociones C enteros también requieren que "si un int puede representar todos los valores del tipo original, el valor se convierte a un int, de lo contrario, se convierte a un unsigned int."

Mi pregunta es en el caso de una expresión de lenguaje C, donde unsigned int y signed int están presentes, el tipo será promovido a qué tipo?

E.g. int no puede representar todos los valores de los unsigned int (valores mayores que MAX_INT valores), mientras que unsigned int no pueden representar los valores -ve, por lo que tipo es promovido a lo que en estos casos?

+3

se parece a la última frase del párrafo 1 del 6.3.1.8 se aplica - ambos son "convertido" a unsigned int. –

Respuesta

22

Creo que el siguiente responde a su pregunta:

6.3.1.3 y sin signo de números enteros

Cuando un valor de tipo entero se convertir en otro tipo entero que no sea _Bool, si el valor se puede representado por el nuevo tipo, es sin cambios.

lo contrario, si el nuevo tipo está sin firmar, el valor es convertido mediante la adición repetida o restando uno más que el valor máximo que se puede representar en el nuevo tipo de hasta que el valor está en el rango del nuevo tipo.

De lo contrario, el nuevo tipo se firma y el valor no puede ser representado en ella; ya sea el resultado es definido por la implementación o una señal definido por la implementación es elevada.

+0

Esto significa que 'uint32_t i = 70; (int16_t) i; '¿está * implementada la implementación *? – nonsensickle

+7

@nonsensickle: No, '(int16_t) i' debe ser 70, porque 70 está en el rango de' int16_t'. Solo obtiene un comportamiento definido por la implementación si 'i' está fuera del rango de' int16_t'. –

38

Creo que estás confundiendo dos cosas. Promoción es el proceso por el cual los valores de tipo entero "más pequeño" que int/unsigned int se convierten, ya sea a int o unsigned int. Las reglas se expresan de forma algo extraña (sobre todo para el beneficio de manejar adecuadamente el carbón) pero aseguran que el valor y el signo se conserven.

Luego está el concepto diferente de conversión aritmética usual mediante el cual los operandos de operadores aritméticos se convierten a un tipo común. Comienza promocionando el operando (ya sea int o unsigned) si son de un tipo más pequeño que int y luego elige un tipo de destino por el siguiente proceso (para tipos de enteros, 6.3.1.8/1)

If ambos operandos tienen el mismo tipo, entonces no se necesita conversión adicional.

lo contrario, si los dos operandos han firmado tipos de enteros o ambos tienen sin signo tipos de enteros, el operando con el tipo de rango de conversión de número entero menor se convertida al tipo del operando con mayor rango.

De lo contrario, si el operando que tiene tipo entero sin signo tiene mayor rango o igual al rango del tipo del otro operando, a continuación, el operando con firmado tipo entero se convierte en el tipo del operando con unsigned tipo entero

De lo contrario, si el tipo del operando con el tipo entero con signo puede representar todos los valores del tipo del operando con el tipo de número entero sin signo, a continuación, el operando con el tipo entero sin signo se convierte en el tipo de la operando con tipo entero con signo.

De lo contrario, ambos operandos se convierten al entero sin signo tipo correspondiente al tipo del operando con tipo entero con signo.

(Tenga en cuenta que ISTR que esas reglas han cambiado ligeramente entre C89 y C99)

+0

C99 hizo un uso explícito del término "rango" de un tipo integral. Además, vea mi comentario a esta respuesta: http://stackoverflow.com/questions/2032744/unexpected-behavior-when-printing-4-byte-integer-byte-by-byte/2032769#2032769 –

+1

'exprimed' yeesh that me llevó en un salvaje viaje de Wikipedia para buscar su definición. – Qix

Cuestiones relacionadas