Oliver schrieb:
> Schlechte Wahl. Die pointer-Lösung basiert auf dem selben Prinzip wie
> die Lösung mit der Union, ist damit genauso wenig portabel, braucht aber
> wesentlich mehr Zyklen.
Ja, es ist dasselbe Prinzip wie die Lösung mit der Union, ist aber von
der Schreibarbeit weniger aufwendig. Natürlich hast Du recht: Sie ist
genauso wenig portabel wie die Union, da beide abhängig vom "Bytesex"
(Endian) des µCs sind.
Aber im letzten Punkt gebe ich Dir nicht recht. Es kann nicht
"wesentlich mehr" Zyklen brauchen als die Union-Lösung.
Hier ein Auszug aus der lss-Datei (AVR-gcc):
unsigned char * l = (unsigned char *) &Long;
l[0] = Byte1;
b6: 80 91 61 00 lds r24, 0x0061
ba: 80 93 62 00 sts 0x0062, r24
l[1] = Byte2;
be: 80 91 60 00 lds r24, 0x0060
c2: 80 93 63 00 sts 0x0063, r24
l[2] = Byte3;
c6: 80 91 66 00 lds r24, 0x0066
ca: 80 93 64 00 sts 0x0064, r24
l[3] = Byte4;
ce: 80 91 67 00 lds r24, 0x0067
d2: 80 93 65 00 sts 0x0065, r24
Das ist verdammt kurz. Ich wüsste nicht, wo die Union-Lösung da noch ein
Byte einsparen könnte. Von "wesentlich mehr als die Union-Lösung" kann
daher keine Rede sein.
> Wirklich portabel ist nur deine anfangs gezeigte Variante.
Ja, leider. Die Shift-Version kostet das 5-7 fache an Code. Ich würde
trotzdem immer die portable Variante vorziehen, außer man hätte die
Möglichkeit, den Endian des verwendeten Prozessors per Preprocessor
abzufragen. Dann könnte man portabel beide Varianten im Source
platzieren, nämlich in etwa so:
unsigned char * l = (unsigned char *) &Long;
#if BIG_ENDIAN == 1
l[0] = Byte1;
l[1] = Byte2;
l[2] = Byte3;
l[3] = Byte4;
#else
l[0] = Byte4;
l[1] = Byte3;
l[2] = Byte2;
l[3] = Byte1;
#endif
Gruß,
Frank