2016-09-08 2 views
1

Ich habe zwei vorzeichenlose Nummern mit je 32 Bits, die in einem einzigen Array gespeichert sind. Die erste Zahl ist in den Positionen [0; 3] und der zweite in Positionen [4; 8]. Ich jetzt was den Wert einer der Zahlen zu ändern, ist der folgende Code erlaubt/problematisch?Verwenden von uint32_t *, um den Wert des Arrays uint8_t zu ändern

uint8_t array[8]; 
//...Fill it up... 

uint32_t *ptr = NULL; 
ptr = (uint32_t*)&array[0]; 
*ptr = 12345; 

ptr = (uint32_t*)&array[4]; 
*ptr = 54321; 
+5

ja, es ist problematisch http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule –

+2

Sie verstoßen gegen die effektive Regel des Typs (auch als strikte Aliasing bezeichnet) Dies ist ein klares ** nicht **! Verwenden Sie Marshalling mit Bitshifts/masking – Olaf

+1

kann man es auch andersherum machen: habe ein Array von 'uint32_t', das du mit den' uint32_t' Werten füllst. Du kannst dann dieses Array mit einem 'uint8_t *' (solange du nicht von der. gestört wirst Daten Präsentation). –

Antwort

1

Sie können keine uint8_t Array mit einem Zeiger auf uint32_t zuzugreifen. Das ist eine Verletzung von the strict aliasing rule (andersherum wäre ok - wenn uint8_t ein Zeichentyp ist).

Stattdessen könnten Sie verwenden möchten "type punning" die C (C99 und höher) Typ System zu umgehen Dafür Sie eine union mit den Mitgliedern der jeweiligen Typen verwenden.

union TypePunning { 
    uint32_t the_ints[2]; 
    uint8_t the_bytes[2 * sizeof(uint32_t)]; 
} 
// now e.g. write to the_bytes[1] and see the effect in the_ints[0]. 
// Beware of system endianness, though! 
+0

'uint8_t' ist niemals ein Zeichentyp! Es ist immer ein vorzeichenloser Integertyp. Und der andere Weg ist nicht in Ordnung. Siehe 6.5p6, 1. Satz! Und während UB nicht aufgerufen wird, hat der Gewerkschaftsansatz auch seine Probleme. – Olaf

+0

@Olaf, besser zu sagen, dass 'uint8_t' ein Integer-Typ ist und' char' nicht. Der Standard hat keine breitere Kategorie von "Charaktertypen". Insbesondere werden "signed char" und "unsigned char" nicht mit "char" gruppiert, um eine solche Kategorie zu bilden. Die Typen mit Vorzeichen/Vorzeichen sind unter den Integertypen gruppiert. –

+0

@ JohnBollinger: 6.2.5p6, letzter Satz: "... Die standardmäßigen und erweiterten vorzeichenlosen Integertypen werden zusammen als _unsigned integer types_" bezeichnet. 'uint8_t' kann nichts anderes als 'unsigned char' sein, was ein _standard vorzeichenloser Integertyp_ ist. – Olaf

Verwandte Themen