2010-09-02 25 views
9

Encontré el siguiente código, y me dijeron que significa que COL_8888_RED es "endian independiente". ¿Por qué? ¿Qué hace que este endian sea independiente? (He pedido al codificador original, pero que no están recibiendo de nuevo a mí ... diablos quizá que no saben bien.)¿Qué hace que este código sea "endian independiente"?

union _colours { 
    uint8 c[3][4]; 
    uint32 alignment; 
}; 

static const union _colours col_8888 = { 
     { /* B  G  R  A in memory  */ 
       { 0x00, 0x00, 0xFF, 0xFF, }, /* red */ 
       { 0x00, 0xFF, 0x00, 0xFF, }, /* green */ 
       { 0xFF, 0x00, 0x00, 0xFF, }, /* blue */ 
     } 
}; 

#define COL_8888_RED *((uint32 *)&col_8888.c[0]) 
+0

Lo que puede ser endian independiente no es seguro, teniendo en cuenta que algunos hardware diferentes pueden elegir ARGB, BGRA, RGBA, etc. ... –

+0

@ dash-tom-bang, de hecho otros tipos de pantallas requerirán rojo, verde y azul a definir en diferentes órdenes de bytes. Y en este caso, la unión 'col_8888' define rojo, verde y azul para un tipo específico de pantalla y, por lo tanto, define un orden de bytes específico: se usa * solo * para escribir en ese tipo de pantalla. Otros tipos de pantallas requerirán diferentes definiciones de rojo, verde y azul. – BeeBand

Respuesta

11

Este código no es "endian-independiente" en una Tenga en cuenta que las plataformas con endianness diferente le dará diferentes valores vistos a través de COL_8888_RED. En otras palabras, en la comprensión tradicional de la dependencia de Endian, este código es tan dependiente de Endian como siempre.

Una pregunta diferente es dónde se supone que se usa COL_8888_RED. Tal vez esté destinado a pasar a alguna API, que en sí misma depende de Endian de la misma manera hasta el punto de que la dependencia endian de la API anula la dependencia endian de COL_8888_RED. En ese caso, todo funcionará "según lo previsto", es decir, endian-independientemente. (Por ejemplo, si la API recibe el valor de color como uint32 y luego lo separa en los componentes ARGB utilizando la misma unión, obtendrá los valores ARGB originales correctos independientemente de la endiancia).

Pero, no obstante, para decir que el valor de COL_8888_RED por sí mismo es endian-independent es totalmente incorrecto.

+1

@Andrey, ¿sería mejor un término "agnóstico de Endian"? – BeeBand

+0

@BeeBand, a continuación, vemos la pregunta "¿Por qué este código endian agnóstico". El mismo grado de averiguarlo entrará en cualquier otro término utilizado. – maxwellb

+0

@Andrey, 'COL_8888_RED' se escribirá directamente en un elemento de una matriz de' uint32'. – BeeBand

2

Supongo que COL_8888_RED, como una macro, siempre será un uint32, que, siempre que se use siempre la macro COL_8888_RED, la matriz de bytes de origen {0x00,0x00,0xFF, 0xFF} siempre se traducirá en lo que programador quiere decir como ROJO.

La definición, entonces, significa que puede escribir el mismo código fuente en una máquina endian grande, o little endian, y pasar de una matriz discreta a un color lógico.

EDITAR: ¿por qué entonces, no utiliza una enumeración, o una constante como "1"?

Probablemente, el desarrollador API original, quería ser capaz de apuntar a otra ubicación de {0x00,0x00,0xFF, 0xFF} en la memoria, por lo que el siguiente código como se podría escribir:

uint8 *p = malloc(sizeof(uint8)*4); 

fread(p, sizeof(uint8), 4, inBuff); 

if(*((uint32 *)p) == COL_8888_RED) 
{ 
    printf("I read red!\n"); 
} 
+0

FWIW, el lanzamiento de este tipo no cumple con las reglas de alias estrictos, lo que realmente puede causar problemas, especialmente con la optimización activada. –

3

matrices de bytes son endianness independientes en casi todas las arquitecturas. Al asignarlo como una matriz de bytes, el programador garantiza un contenido consistente para los datos. También se puede acceder a los bytes de forma individual en cualquier arquitectura. Si el codificador acaba de hacer una matriz de 3 palabras, la endianidad de la máquina jugaría un papel en la determinación del diseño exacto de los bits.

Cuestiones relacionadas