endianness bestimmen
-
osdt schrieb:
Nathan schrieb:
Das ist vollkommen egal, da das Lesen des nicht aktiven Unionmembers sowieso UB ist.
Das bezieht sich meines Wissens nur auf nicht-triviale Typen, deren Konstuktor explizit aufgerufen werden muss. Nur in diesem Zusmmenhang macht der Term 'aktiver Member' überhaupt Sinn. Ich lasse mich natürlich gern eines Besseren belehren.
Arcoth schrieb:
Das ist vollkommen egal, da das Lesen des nicht aktiven Unionmembers sowieso UB ist.
Das ist (pauschal) offensichtlich falsch.
type-punning via union verletzt die strict aliasing rule (§3.10/10), das ist UB.
Lesen ist aber mindestens implementation-defined, wenn nicht ebenfalls UB.
Welches Lesen?
In dem verlinktem Code:
bool isLittleEndian() { short int number = 0x1; char *numPtr = (char*)&number; return (numPtr[0] == 1); // hier }
Aliasing via char* ist erlaubt, aber wenn man das dann als char liest, ist das Ergebnis definitiv nicht portabel.
-
Aliasing via char* ist erlaubt, aber wenn man das dann als char liest, ist das Ergebnis definitiv nicht portabel.
Ja, die value representation ist implementation-defined. UB ist es aber definitiv nicht, sondern explizit erlaubt.
type-punning via union verletzt die strict aliasing rule (§3.10/10), das ist UB.
Kleiner Tipp: Die Member einer Union müssen nicht alle von völlig unterschiedlichem Typ sein.
-
Arcoth schrieb:
Aliasing via char* ist erlaubt, aber wenn man das dann als char liest, ist das Ergebnis definitiv nicht portabel.
Ja, die value representation ist implementation-defined. UB ist es aber definitiv nicht, sondern explizit erlaubt.
Ja, deshalb schrieb ich das ja.
type-punning via union verletzt die strict aliasing rule (§3.10/10), das ist UB.
Kleiner Tipp: Die Member einer Union müssen nicht alle von völlig unterschiedlichem Typ sein.
*sigh*
Ja, dann verletzt es nicht die strict aliasing rule. Garantiert das man den selben Wert bekommt, den man rein gesteckt hat ist das aber glaub ich immer noch nicht.
-
osdt schrieb:
coder007 schrieb:
kann man endianness zur compile time bestimmen?
Sollte funktionieren:
constexpr bool is_little_endian() { union helper { int i; char c; }; return helper{1}.c; }
Edit: garantiert der Standard, dass
helper::c
im 1. Byte von helper liegt? Ansonsten wärechar c[sizeof(int)]
undhelper{1}.c[0]
wohl ehr Standardkonform.Sollte nicht funktionieren.
2 A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the
abstract machine (1.9), would evaluate one of the following expressions:
[...]
— an lvalue-to-rvalue conversion (4.1) or modification (5.17, 5.2.6, 5.3.2) that is applied to a glvalue that
refers to a non-active member of a union or a subobject thereof;Das Standardkomitee hat solche Konstrukte ganz bewusst nicht konstant gemacht um die Implementation u.a. von cross-Compilern nicht zu erschweren.
-
LOL, Extrapunkte für osdt, weil er ein Konstrukt geschrieben hat, dass explicit vom Standard verboten ist. Respekt.
-
was ist nun die eine moegliche loesung?
-
Nathan schrieb:
LOL, Extrapunkte für osdt, weil er ein Konstrukt geschrieben hat, dass explicit vom Standard verboten ist. Respekt.
Da kannst du mal sehen was mit etwas gutem Willen alles möglich ist
GCC (4.9.1) compiliert das ohne Murren und ich hab gedacht 'wird schon passen'.
Leider musste ich eben feststellen, dass clang (3.5) anderer Meinung ist:
prog.cc:10:22: note: read of member 'c' of union with active member 'i' is not allowed in a constant expression
Tja, dumm gelaufen. Ich nehme alles zurück und gelobe Besserung.
-
coder007 schrieb:
vorbereitung coding interview...
Wie kommst du eigentlich gerade auf diese Frage?
coder007 schrieb:
was ist nun die eine moegliche loesung?
Mögliche Lösung: In C++ gibt es keine Endianness.
-
Whenever I see code that asks what the native byte order is, it's almost certain the code is either wrong or misguided.
-
@pike: as i said its a coding interview question...