2010-09-02 11 views
9

Ich stieß auf den folgenden Code, und wurde gesagt, dass es bedeutet, dass COL_8888_RED ist "endian unabhängig". Warum? Was macht diesen Endian unabhängig? (Ich habe die ursprünglichen Codierer gefragt, aber sie sind nicht wieder zu mir bekommen ... Heck vielleicht sie weiß es auch nicht.)Was macht diesen Code "endian unabhängig"?

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

Was endian unabhängig sein kann, ist nicht sicher, wenn man bedenkt, dass einige andere Hardware ARGB, BGRA, RGBA, usw. wählen können ... –

+0

@ dash-tom-bang, ja, andere Arten von Displays benötigen rot, Grün und Blau müssen in verschiedenen Byte-Reihenfolgen definiert sein. Und in diesem Fall definiert die 'col_8888'-Vereinigung rot, grün und blau für eine bestimmte Art von Anzeige und definiert somit eine bestimmte Byte-Reihenfolge - sie wird nur * verwendet, um auf diese Art von Anzeige zu schreiben. Andere Anzeigetypen erfordern unterschiedliche Definitionen von Rot, Grün und Blau. – BeeBand

Antwort

11

Dieser Code nicht „Endian-unabhängig“ in a empfinden Sie, dass Plattformen mit unterschiedlicher Endianz Ihnen verschiedene Werte geben, die durch COL_8888_RED gesehen werden. Mit anderen Worten, im traditionellen Verständnis der Endian-Abhängigkeit ist dieser Code so endianabhängig, wie er überhaupt wird. Eine andere Frage ist wo COL_8888_RED verwendet werden soll. Vielleicht ist es beabsichtigt, an eine API übergeben zu werden, die für sich selbst endianabhängig ist, bis zu dem Punkt, dass die Endian-Abhängigkeit der API die Endian-Abhängigkeit von COL_8888_RED löscht. In diesem Fall wird alles "wie beabsichtigt" arbeiten, d. H. Endian-unabhängig. (Wenn die API beispielsweise den Farbwert uint32 empfängt und sie dann mithilfe derselben Union in die ARGB-Komponenten aufteilt, erhält sie unabhängig von der Endianität die korrekten Original-ARGB-Werte.)

Aber trotzdem, um das zu sagen der Wert von COL_8888_RED an sich ist endian-unabhängig ist völlig falsch.

+1

@Andrey, wäre ein besserer Ausdruck dann "endian agnostic"? – BeeBand

+0

@BeeBand, dann sehen wir die Frage "Warum ist dieser Code endian agnostic". Der gleiche Grad der Ermittlung wird in jedem anderen verwendeten Begriff gehen. – maxwellb

+0

@Andrey, 'COL_8888_RED' wird direkt in ein Element in einem Array von' uint32' geschrieben. – BeeBand

2

Ich nehme an, dass COL_8888_RED, als ein Makro, immer ein uint32 ist, das, solange das Makro COL_8888_RED immer verwendet wird, das Quellbytearray {0x00,0x00,0xFF, 0xFF} immer in das übersetzt Programmierer möchte als ROT bedeuten.

Die Definition bedeutet also, dass Sie denselben Quellcode auf einem Big Endian oder Little Endian-Computer schreiben können und von einem diskreten Array zu einer logischen Farbe wechseln können.

EDIT: Warum verwenden Sie dann keine Enumeration oder eine Konstante wie "1"?

Wahrscheinlich, die Original-API-Entwickler wollten an einem anderen Ort von {0x00,0x00,0xFF, 0xFF} im Speicher zeigen zu können, so dass Code wie die folgenden geschrieben werden könnte:

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, Casting wie dieses fällt unter strikte Aliasing-Regeln, die wirklich Probleme verursachen können, besonders bei eingeschalteter Optimierung. –

3

Arrays von Bytes sind endianess unabhängig von fast allen Architekturen. Indem er ihm als Byte-Array zuordnet, stellt der Programmierer konsistenten Inhalt für die Daten sicher. Auf die Bytes kann auch individuell in jeder Architektur zugegriffen werden. Wenn der Codierer gerade ein Array von 3 Wörtern erstellt hätte, würde die Maschinenendiannität eine Rolle bei der Bestimmung des genauen Layouts der Bits spielen.