MinGW: __attribute__((packed)) und alignment

OP #4481383
Lesenswert?
• ▲
▼
Hallo zusammen,

ich habe ein struct definiert mit:
1
__extension__ typedef struct 
2
{
3
    uint16_t val0: 10; 
4
    uint16_t val1: 10;
5
    uint8_t crc : 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.
Moderator Persönliche Seite #4481455
Lesenswert?
• ▲
▼
Seltsam:
1
$ cat foo.c
2
#include <stdint.h>
3

4
__extension__ typedef struct 
5
{
6
    uint16_t val0: 10; 
7
    uint16_t val1: 10;
8
    uint8_t crc : 4; 
9
} __attribute__((packed)) Eedata_t;
10

11
Eedata_t foo;
12

13
int getval1(Eedata_t *p)
14
{
15
   return p->val1;
16
}
17
$ cc -O -S foo.c
18
$ cat foo.s
19
        .file   "foo.c"
20
        .text
21
        .globl  getval1
22
        .type   getval1, @function
23
getval1:
24
.LFB0:
25
        .cfi_startproc
26
        movzbl  1(%rdi), %edx
27
        shrb    $2, %dl
28
        movzbl  %dl, %edx
29
        movzbl  2(%rdi), %eax
30
        andl    $15, %eax
31
        salq    $6, %rax
32
        orl     %edx, %eax
33
        ret
34
        .cfi_endproc
35
.LFE0:
36
        .size   getval1, .-getval1
37
        .comm   foo,3,1
38
        .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4"
39
        .section        .note.GNU-stack,"",@progbits

Kann mir nicht vorstellen, dass sich ein MinGW32 anders verhält als
der Compiler hier unter Linux.
OP #4481563
Lesenswert?
• ▲
▼
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.
OP #4481740
Lesenswert?
• ▲
▼
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:
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  1(%rcx), %eax
9
  shrb  $2, %al
10
  movzbl  %al, %edx
11
  movzbl  2(%rcx), %eax
12
  andl  $15, %eax
13
  salq  $6, %rax
14
  orl  %edx, %eax
15
  ret
16
  .seh_endproc
17
  .comm  foo, 4, 0
18
  .ident  "GCC: (tdm64-1) 5.1.0"

bzw. der "sizeof"-Operator liefert 4 zurück.
OP #4481885
Lesenswert?
• ▲
▼
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.)

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.