Konvertierung Frage
-
Th69 schrieb:
Hallo Xin,
laut C++ Standard aber undefiniertes Verhalten - es darf nur aus dem Union-Member gelesen werden, in dem zuletzt reingeschrieben wurde (auch wenn dieser Union-Cast überaus beliebt ist)!
Natürlich ist das Verhalten in C++ undefiniert, schon alleine weil das Integer von einer Motorola CPU anders geschrieben wird als von einem Intel oder es CPUs gibt, für die C-Compiler existieren, die aber eine Bytegröße von über 32 Bit haben, ergo ein int auch größer als 32 Bit ist.
Wie der Fragesteller schon sagte: Windows kompatibel und er möchte nicht auf 5% Sonderfälle eingehen. Dafür ist diese Lösung tragbar.
-
Xin schrieb:
Das Union bietet sich zum Beispiel an, wenn Du 4 Byte aus einer Datei einlädst und dafür einen char-Pointer brauchst, diese vier Byte aber in wirklichkeit eben ein int sind.
Genau das mache ich auch, ich habe eine Binärdatei vorliegen und weis das gewisse 4 Bytes eben ein unsigned int sind. Ich denke ich werde die reinterpret_cast<..>(..) Lösung nehmem, das mit dem union ist mir irgendwie suspekt. Vielen Dank!
-
KnobelDran schrieb:
Ich denke ich werde die reinterpret_cast<..>(..) Lösung nehmem, das mit dem union ist mir irgendwie suspekt.
Sehe ich auch als die bessere Variante an (wenns denn not tut das so zu machen). UB bzw. Plattformspezifisch ist beides, allerdings sieht man beim reinterpret_cast sofort, dass da was ungewöhnliches passiert. Den wechselnden Zugriff auf verschiedene union-Elemente kann man schnell mal übersehen.
-
KnobelDran schrieb:
Xin schrieb:
Das Union bietet sich zum Beispiel an, wenn Du 4 Byte aus einer Datei einlädst und dafür einen char-Pointer brauchst, diese vier Byte aber in wirklichkeit eben ein int sind.
Genau das mache ich auch, ich habe eine Binärdatei vorliegen und weis das gewisse 4 Bytes eben ein unsigned int sind. Ich denke ich werde die reinterpret_cast<..>(..) Lösung nehmem, das mit dem union ist mir irgendwie suspekt. Vielen Dank!
Ich nehme diese Lösung in der Regel auch, bzw. ich habe eine Endian-Class, die sich in Abhängigkeit des Prozessortyps initialisiert. Der gebe ich mit, was ich für Daten lese (char/short/int...) und welche Endianess ich erwarte. Anschließend frage ich nur noch den Wert ab.
Der Umgang ist also ähnlich mit dem Union.Ein reinterpret_cast<> sollte Dir aber auch sehr suspekt sein.
Du solltest also eventuell in einem Kommentar dokumentieren, was das soll, denn ein reinterpret_cast<> ist ein klarer Hinweis auf ein Problem, eine offenliegende Wunde in der Architektur. Der Kommentar wirkt da als Pflaster.
-
Warum liest dunicht direkt in den int ein, ala:
int i; lies_nach(&i, sizeof i);
-
Könnte ich, wenn du mir sagst welchen Vorteil das gegenüber der Funktion mit return hat und ich den Vorteil als solchen anerkenne :p .
Bei der Funktion hab ich die Möglichkeit den Wert sofort weiterzuverarbeiten.
z.B.std::cout<<BytesToInt32(someChars);
-
Einige Compiler bieten aber Unions als "Workaround" gegen die Strict-Aliasing rule an. (z.B. GCC gcc.gnu.org/bugs/#known )
-
Also
uint32_t BytesToInt32(const uint8_t* B) { return B[0]+(B[1]<<0x8)+(B[2]<<0x10)+(B[3]<<0x18); }macht bereits das Richtige? Wieso werden dann memcpy oder absurde Casts überhaupt in Erwägung gezogen?
-
camper schrieb:
Also
uint32_t BytesToInt32(const uint8_t* B) { return B[0] // zugriff + // addition (B[1] // addition und zugriff << // shiften 0x8) + // addition (B[2] // addition und zugriff << // shiften 0x10) + // addition (B[3] // addition und zugriff << // shift 0x18); }macht bereits das Richtige? Wieso werden dann memcpy oder absurde Casts überhaupt in Erwägung gezogen?
return * // Zugriff (unsigned __int32*)(B);
-
Xin schrieb:
camper schrieb:
Also
uint32_t BytesToInt32(const uint8_t* B) { return B[0] // zugriff + // addition (B[1] // addition und zugriff << // shiften 0x8) + // addition (B[2] // addition und zugriff << // shiften 0x10) + // addition (B[3] // addition und zugriff << // shift 0x18); }macht bereits das Richtige? Wieso werden dann memcpy oder absurde Casts überhaupt in Erwägung gezogen?
return * // Zugriff (unsigned __int32*)(B);Ja, ich habe mir schon gedacht, dass es etwas mit Voodoo zu tun haben muss...