2012-06-26 9 views
7

Similar a la pregunta Bitshift and integer promotion?, tengo una pregunta acerca de la promoción de enteros al usar cambios de bits izquierdos.Promoción de enteros con el operador <<

unsigned int test(void) 
{ 
    unsigned char value8; 
    unsigned int result; 

    value8 = 0x12; 
    result = value8 << 8; 
    return result; 
} 

En este caso, será la primera valor8 promover a unsiged int o es específico de la implementación?

6.5.7 bit a bit operadores de desplazamiento ... 3 Sematics ...
Las promociones enteros se realizan en cada uno de los operandos. El tipo de resultado es el del operando izquierdo promocionado. Si el valor del operando derecho es negativo o es mayor o igual que el ancho del operando izquierdo promocionado, el comportamiento no está definido.

Dice que el "Las promociones enteras se realizan en cada uno de los operandos"., pero ¿cuál es aquí la regla de promoción?

Supongo que debería ser convert to int if lesser rank than int, pero no puedo encontrarlo.

Pregunto esto, ya que un compilador (Renesas nc30wa) no promociona a int, por lo que el resultado es siempre 0 para mi muestra.

En esta plataforma, un char es de 8 bits de ancho e int 16 bits.

+2

Si value8 no se promociona, es un error del compilador. –

+1

Al parecer esa es la pregunta, ¿es un error o una implementación específica? – jeb

+0

@jeb Vea la edición en mi respuesta, algunos compiladores deshabilitan las promociones enteras por defecto y lo documenta en la documentación del compilador. Debe buscar la conformidad ISO en la documentación del compilador. – ouah

Respuesta

12

La frase "las promociones enteros" es una cosa muy específica, que se encuentra en (para C99) sección 6.3.1.1 Booleans, characters, and integers:

Si un int puede representar todos los valores del tipo original, el valor se convierte a una En t; de lo contrario, se convierte en un int sin firmar. Estas se llaman promociones enteras . Todos los otros tipos no se modifican por las promociones enteras.

Así que asumiendo que su unsigned char puede ser mantenido en un int, que será promovido a una int. En esas raras plataformas donde unsigned char es tan ancho como int, se promocionará a unsigned int.

Esto sólo se cambia ligeramente en C11:

Si un int puede representar todos los valores del tipo de original (como restringida por el ancho, para un campo de bits ), el valor se convierte a una En t; de lo contrario, se convierte en un sin signo int.Estas se llaman promociones enteras. Todos los otros tipos no se modifican mediante las promociones enteras .

Si un compilador específico no sigue este comportamiento, entonces no es realmente conforme. Sin embargo, dado que el compilador que enumeró es para sistemas integrados, no es realmente sorprendente.

Muchos están diseñados para fines específicos y la conformidad no siempre es alta en la lista de requisitos. Puede haber indicadores del compilador que le permitan ajustarse más estrechamente al estándar.


En cuanto a su entorno particular, , la M16C Series,R8C Family C Compiler Package V.5.45 C Compiler (ver here) tiene, en la sección 2.1.4 nc30 Command Line Options, inciso f. Generated code modification options:

-fextend_to_int (-fETI):
          Realiza la operación después de extender los datos de tipo char al tipo int. Extendido según los estándares de ANSI.

aunque sospecho que -fansi es probablemente una mejor opción ya que también cubre algunas otras cosas.

3

value8 es promovido a int, asumiendo que el rango de conversión de unsigned char es menor que el rango de conversión de int (generalmente el caso en la mayoría de las plataformas).

Los rangos de conversión de los enteros se describen en C99 en 6.3.1.1.

Tenga en cuenta que algunos compiladores deshabilitan las reglas de promociones enteras de forma predeterminada. Por ejemplo, el compilador MicroChip MPLAB C18. Busque la conformidad ISO en la documentación de su compilador.