2016-08-03 24 views
0

Kopieren Bitmusters eines float Wert in eine uint32_t oder umgekehrt (nicht sie Guss), können wir Bits Byte-zu-Byte kopieren std::copy oder memcpy verwenden. Ein anderer Weg ist reinterpret_cast zu verwenden, wie unten:Copy Bitmusters: float uint32_t

float f = 0.5f; 
uint32_t i = *reinterpret_cast<uint32_t*>(&f); 

oder

uint32_t i; 
reinterpret_cast<float&>(i) = 10; 

jedoch ein claim ist, die sagt, zwei reinterpret_cast oben verwendete, nicht definiertes Verhalten aufzurufen.

Stimmt das? Wie?

+1

Wie von der Antwort angegeben, ist es UB. Eine Aussage, dass "sizeof (uint32_t) == sizeof (float)" sollte alles sein, was Sie brauchen, um sicher zu sein, dass es funktioniert. – NathanOliver

+0

@NathanOliver Aber wenn der Compiler typenbasierte Alias-Optimierungen durchführt, dann könnte es das Verhalten vernünftigerweise unterbrechen, wenn Sie '-fno-strict-aliasing' oder etwas nicht liefern. – TartanLlama

+0

@TartanLlama Guter Punkt. Die Überprüfung von 'alignof' könnte ebenfalls erforderlich sein. – NathanOliver

Antwort

6

Ja, das ist nicht definiertes Verhalten, wie es die strenge Aliasing Regel bricht:

[basic.lval]/10: Wenn ein Programm versucht, den gespeicherten Wert eines Objekts durch einen glvalue anderer als einer der folgenden Arten zugreifen die Verhalten ist undefiniert - der dynamische Typ des Objekts,

- eine cv-qualifizierte Version des dynamischen Typs des Objekts,

- eine Art ähnlich (wie in 4.4 definiert) bis t er dynamischer Typ des Objekts,

- ein Typ, der mit oder ohne Vorzeichen-Typen entsprechend den dynamischen Typen des Objekts,

- ein Typ, der mit oder ohne Vorzeichen-Typen entsprechend einem cv-qualifiziert Version des dynamischen Typs des Objekts,

- ein Aggregat oder Union Typ, der eine des oben genannten Typs unter seinen Elementen oder nicht statische Datenelementen (einschließlich, rekursiv umfasst, ein Element oder ein nicht-statisches Datenelement eines Unteraggregats oder enthaltenen Union),

- ein Typ, der ein (möglicherweise cv-qualifizierter) Basisklassentyp des dynamischen Typs des Objekts ist,

- ein char oder unsigned char type.

Da uint32_t keine der oben ist, wenn ein Objekt vom Typ zuzugreifen versuchen float, ist das Verhalten nicht definiert.