This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

-Wpacked in gcc manual page question


I don't understand the -Wpacked description from the GCC manual page, it reads:

      -Wpacked
Warn if a structure is given the packed attribute, but the packed attribute has no effect on the layout or size of the structure. Such structures may be mis-aligned for little benefit. For instance, in this
           code, the variable "f.x" in "struct bar" will be misaligned even though "struct bar" does not itself have the packed attribute:

                   struct foo {
                     int x;
                     char a, b, c, d;
                   } __attribute__((packed));
                   struct bar {
                     char z;
                     struct foo f;
                   };


why does the "__attribute__((packed))" for struct foo cause misalignment for struct bar ?

I would expect misalignment only if struct bar is defined with __attribute__((packed))
or its member f.

I thought __attribute__((packed)) only works for (the members of) the struct, but apparently
it tries to avoid 3 bytes extra padding in struct bar. However, sizeof(struct bar) = 12 !?
so there still is 3 bytes padding *and* misalignment. Why would anyone ever want this gcc behaviour ?

This case corresponds to case 3 of my simple test program, see below:

linpc166:~/c/alignment>cat -n t.c
     1  #include <stdio.h>
     2
     3  struct foo {
     4          int x;
     5          char a, b, c, d;
     6  };
     7
     8  struct foo2 {
     9          int x;
    10          char a, b, c, d;
    11  } __attribute__ ((__packed__));
    12
    13
    14  struct bar {
    15          char z;
    16          struct foo f;
    17  };
    18
    19  struct barp {
    20          char z;
    21          struct foo f;
    22  } __attribute__ ((__packed__));
    23
    24  struct bar2 {
    25          char z;
    26          struct foo2 f;
    27  };
    28
    29  struct bar2p {
    30          char z;
    31          struct foo2 f;
    32  } __attribute__ ((__packed__));
    33
    34
    35  int main(void)
    36  {
    37          struct bar b;
    38          struct barp bp;
    39          struct bar2 b2;
    40          struct bar2p b2p;
    41
    42          printf("case 1(b): sizeof(struct foo)=%ld, sizeof(struct bar)=%ld\n", sizeof(struct foo), sizeof(struct bar));
    43          if ((((unsigned long)&b.f.x) - ((unsigned long)&b.z)) & 0x3) {
    44                  printf("case 1(b): MIS-ALGND\n");
    45          } else {
    46                  printf("case 1(b): ALGND\n");
    47          }
    48          printf("\ncase 2(bp): sizeof(struct foo)=%ld, sizeof(struct barp)=%ld\n", sizeof(struct foo), sizeof(struct barp));
    49          if ((((unsigned long)&bp.f.x) - ((unsigned long)&bp.z)) & 0x3) {
    50                  printf("case 2(bp): MIS-ALGND\n");
    51          } else {
    52                  printf("case 2(bp): ALGND\n");
    53          }
    54          printf("\ncase 3(b2): sizeof(struct foo2)=%ld, sizeof(struct bar)=%ld\n", sizeof(struct foo2), sizeof(struct bar));
    55          if ((((unsigned long)&b2.f.x) - ((unsigned long)&b2.z)) & 0x3) {
    56                  printf("case 3(b2): MIS-ALGND\n");
    57          } else {
    58                  printf("case 3(b2): ALGND\n");
    59          }
    60          printf("\ncase 4(b2p): sizeof(struct foo2)=%ld, sizeof(struct barp)=%ld\n", sizeof(struct foo2), sizeof(struct barp));
    61          if ((((unsigned long)&b2p.f.x) - ((unsigned long)&b2p.z)) & 0x3) {
    62                  printf("case 4(b2p): MIS-ALGND\n");
    63          } else {
    64                  printf("case 4(b2p): ALGND\n");
    65          }
    66
    67          return 0;
    68  }
linpc166:~/c/alignment>gcc -g -Wpacked -Wall t.c
t.c:11:1: warning: packed attribute is unnecessary for 'foo2'
t.c:32:1: warning: packed attribute is unnecessary for 'bar2p'
linpc166:~/c/alignment>./a.out
case 1(b): sizeof(struct foo)=8, sizeof(struct bar)=12
case 1(b): ALGND

case 2(bp): sizeof(struct foo)=8, sizeof(struct barp)=9
case 2(bp): MIS-ALGND

case 3(b2): sizeof(struct foo2)=8, sizeof(struct bar)=12
case 3(b2): MIS-ALGND

case 4(b2p): sizeof(struct foo2)=8, sizeof(struct barp)=9
case 4(b2p): MIS-ALGND


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]