Hallo zusammen,
ich habe ein struct definiert mit:
1
__extension__typedefstruct
2
{
3
uint16_tval0:10;
4
uint16_tval1:10;
5
uint8_tcrc:4;
6
}__attribute__((packed))Eedata_t;
und baue das Ganze unter MinGW64 (eine GCC-Ausprägung für Windows).
Sizeof von Eedata_t liefert 5 - d.h. der Compiler mag das struct nicht
packen, sondern richtet es an 16-Bit-Grenzen aus.
Gibt es eine Möglichkeit, dem Compiler beizubiegen, ohne Rücksicht auf
Optimierungsverluste und nötigen Schiebeoperationen das Ganze auf 24 Bit
zu packen oder muß ich in den sauren Apfel beißen und von Hand schieben?
Viele Grüße
W.T.
Jörg W. schrieb:> Kann mir nicht vorstellen, dass sich ein MinGW32 anders verhält als> der Compiler hier unter Linux.
Schwer zu sagen: Ich nutze und Windows MinGW64 und unter Linux Clang64.
Aber ich baue mal ein funktionierendes Minimalbeispiel.
Mit Clang auf FreeBSD war der generierte Code etwas umständlicher,
aber dennoch klar und deutlich gepackt auf 3 Bytes.
Wie sieht denn obiges Minimalbeispiel mit gleichen Compileroptionen
bei dir unter MinGW64 aus?
OK, wir haben uns etwas gedoppelt:
Unter Clang habe ich auch 3 Bytes als Größe (sowohl bei Deinem als auch
meinem Minimalbeispiel).
Bei Deinem Minimalbeispiel unter MinGW64:
1
.file "foo.c"
2
.text
3
.globl getval1
4
.def getval1; .scl 2; .type 32; .endef
5
.seh_proc getval1
6
getval1:
7
.seh_endprologue
8
movzbl 2(%rcx), %edx
9
movzbl 3(%rcx), %eax
10
andl $3, %eax
11
salq $8, %rax
12
orl %edx, %eax
13
ret
14
.seh_endproc
15
.comm foo, 5, 0
16
.ident "GCC: (tdm64-1) 5.1.0"
Für mich ist X64/X86er-Asm kryptisch, aber auf den ersten Blick sieht
das nach einem anderen Offset aus.
Walter T. schrieb:> Für mich ist X64/X86er-Asm kryptisch, aber auf den ersten Blick sieht> das nach einem anderen Offset aus.
Ja, insbesondere hast du da "comm foo, 5, 0" stehen, also 5 Bytes.
Sehr seltsam. OK, ist natürlich ein GCC 5.x, habe ich hier gerade
nicht zur Hand.
uint16_t etc. als Basis-Typ für Bitfeld ist ja implementation defined
bzw. deren Unterstützung ist noch nicht einmal vom Standard
vorgeschrieben. Gibt es mit unsigned das gleiche Ergebnis? Und was
passiert mit aligned(1)?
Jörg W. schrieb:> Johann L. schrieb:>> Gibt es mit unsigned das gleiche Ergebnis?>> Bzw. unsigned char / unsigned short?
"unsigned" bringt noch eine neue Variante ins Spiel:
Ich hab's produktiv mit Bitschieberei gelöst - auch wenn mir type
punning über Bitfelder lieber ist (da wartbarer).
Es verbleibt also nur die Neugier, warum GCC 5.1.0 und Clang
unterschiedlicher Meinung sind, was ihre Interpretation von "packed"
angeht.
(Ich bitte von Vorschlägen à la "nimm eine andere GCC-Version"
abzusehen. Diese Distribution mit MinGW64/TDM-GCC arbeitet hervorragend
als MEX-Compiler mit Matlab zusammen - was andere Versionen leider
(noch) nicht tun.)
Adib schrieb:> Man muss bei dem MinGW Compiler noch folgende Option> setzen:-mno-ms-bitfields
Danke für den Hinweis!
Mit der obengenannten Compileroption bzw. dem Attribut
1
__attribute__((gcc_struct))
kommt das erwartete gepackte struct mit 3 Bytes Breite heraus.
Jetzt kann ich meinen Quelltext wieder Zurück-Ändern.