public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: structure packing
@ 2014-01-16 10:45 vijay nag
  2014-01-16 11:34 ` David Brown
  0 siblings, 1 reply; 8+ messages in thread
From: vijay nag @ 2014-01-16 10:45 UTC (permalink / raw)
  To: gcc-help

Dear gcc,

Why is the size of below struct UnPackedStruct 6 ? Is there any switch
similar to -E in gcc to check how data alignment is performed by GCC
for structs ?


#include <stdio.h>
#include <stdint.h>

struct tlv_header_t {
    unsigned char tlv_length_upper : 3;
    unsigned char reserved : 5;
    unsigned char tlv_length_lower;
    uint16_t tlv_type;
};

typedef struct {
  struct tlv_header_t  sess;
  uint8_t p;
} UnPackedStruct;

typedef struct {
   int a;
   char b;
} PaddedStruct;

int main()
{
  UnPackedStruct a;
  PaddedStruct b;

  printf("size of a = %u\n", sizeof(a));
  printf("size of b = %u\n", sizeof(b));

  return 1;
}

./padding
size of a = 6
size of b = 8

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: structure packing
  2014-01-16 10:45 structure packing vijay nag
@ 2014-01-16 11:34 ` David Brown
  0 siblings, 0 replies; 8+ messages in thread
From: David Brown @ 2014-01-16 11:34 UTC (permalink / raw)
  To: vijay nag, gcc-help

On 16/01/14 11:45, vijay nag wrote:
> Dear gcc,
> 
> Why is the size of below struct UnPackedStruct 6 ? Is there any switch
> similar to -E in gcc to check how data alignment is performed by GCC
> for structs ?
> 

What were you expecting for the sizes?  gcc is following the packing and
alignment rules of C and your current platform (I'm guessing it is x86 -
certainly something with 32-bit ints with 32-bit natural alignment).

The first two fields of tlv_header_t are packed into a single 8-bit
unsigned char.  You then have another 8-bit field, so the 16-bit
tlv_type is placed immediately with 2-byte alignment.  tlv_header_t is
thus 4 bytes in size, with a 2-byte alignment.

In UnPackedStruct, you have a 4-byte field with 2-byte alignment,
followed by a 1-byte field.  But the struct must be at least a multiple
of 2 bytes, so that arrays of it will have 2-byte alignment (required
for the tlv_header_t field).  Thus the compiler adds a padding byte,
bringing it up to 6 bytes total.

You can use the -Wpadded flag to check when padding is added for
alignment purposes.  And you could use the "packed" attribute on the
structure if you /really/ need tight packing, but be aware that it could
result in inefficient code (and even invalid code on some platforms).
Generally, if you need tight control over the padding and alignment it
is best to use -Wpadded along with explicit "dummy" or "padding" fields
and check the size of the resulting types.

mvh.,

David



> 
> #include <stdio.h>
> #include <stdint.h>
> 
> struct tlv_header_t {
>     unsigned char tlv_length_upper : 3;
>     unsigned char reserved : 5;
>     unsigned char tlv_length_lower;
>     uint16_t tlv_type;
> };
> 
> typedef struct {
>   struct tlv_header_t  sess;
>   uint8_t p;
> } UnPackedStruct;
> 
> typedef struct {
>    int a;
>    char b;
> } PaddedStruct;
> 
> int main()
> {
>   UnPackedStruct a;
>   PaddedStruct b;
> 
>   printf("size of a = %u\n", sizeof(a));
>   printf("size of b = %u\n", sizeof(b));
> 
>   return 1;
> }
> 
> ./padding
> size of a = 6
> size of b = 8
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: structure packing
  2009-05-22  8:01     ` Mohamed Shafi
@ 2009-05-22 13:51       ` Ian Lance Taylor
  0 siblings, 0 replies; 8+ messages in thread
From: Ian Lance Taylor @ 2009-05-22 13:51 UTC (permalink / raw)
  To: Mohamed Shafi; +Cc: gcc-help, Rohit Arul Raj

Mohamed Shafi <shafitvm@gmail.com> writes:

>     I thought so. With STRICT_ALIGNMENT = 1 the compiler makes sure
> that all access are aligned. So irrespective of whether the structure
> is aligned or not to be safe it generates byte access. Am i right?
> If so in the given example the base address is 0 and the offset will
> be known to the compiler. If the compiler is aware of these two
> information can't it decide whether the structure is aligned or not?

I'm not sure.  If the compiler knows the alignment of the specific
object, it may take that into account to override the packed attribute.
However, I would not be surprised if a specific case like casting 0 to
an address does not record the alignment even though it is known, since
that is such an odd case.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: structure packing
  2009-05-22  6:39   ` Ian Lance Taylor
@ 2009-05-22  8:01     ` Mohamed Shafi
  2009-05-22 13:51       ` Ian Lance Taylor
  0 siblings, 1 reply; 8+ messages in thread
From: Mohamed Shafi @ 2009-05-22  8:01 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-help, Rohit Arul Raj

2009/5/22 Ian Lance Taylor <iant@google.com>:
> Mohamed Shafi <shafitvm@gmail.com> writes:
>
>> The below code is compiled using a private port based on GCC 4.1.1.
>>
>> struct data {
>>      int wdata;
>>      int rdata;
>>  };// __attribute__((__packed__));
>>
>> typedef struct data data;
>> #define data_p (*(volatile data *)(0))
>>
>> int main(void)
>> {
>>   data_p.wdata = data_p.rdata;
>> }
>>
>> For the above source code without the 'packed' attribute the assembly
>> code is generated with word-aligned access. But with packed attribute
>> enabled the assembly code is generated with byte access. When i looked
>> into x86 compiler i find that the assembly code generated is same
>> irrespective of whether the attribute is provided or not.
>
> I don't see this.  When I compile the above test case (i.e., the struct
> is not packed) on x86, I see word accesses.
>
         Sorry for the confusion. What i meant was that irrespective
of whether the structure is packed or not the code generated is for
word access. It should be because the compiler is built with
STRICT_ALIGNMENT = 0. But in my compiler it is byte access for packed
structure and my compiler is built with STRICT_ALIGNMENT = 1.

>> In case,
>> 1) if the packing is enabled and all the data elements inside the
>> struct are by default word-aligned (all the 32bit integers) is it
>> possible to generate word-aligned assembly code?
>
> No.  The packed attribute tells the compiler that the struct may be
> misaligned.

    I thought so. With STRICT_ALIGNMENT = 1 the compiler makes sure
that all access are aligned. So irrespective of whether the structure
is aligned or not to be safe it generates byte access. Am i right?
If so in the given example the base address is 0 and the offset will
be known to the compiler. If the compiler is aware of these two
information can't it decide whether the structure is aligned or not?

Shafi
>
>> 2) Packing is enabled for a structure with different data elements.
>>
>> i.e.
>> struct data {
>>      int wdata;
>>     char t;
>>      int rdata;
>>  } __attribute__((__packed__));
>>
>> Is it possible to generate code like:
>> wdata -> word aligned access.
>> rdata -> byte aligned access.
>
> No.  You could try putting a packed struct inside the unpacked struct,
> though; I don't know whether or not that would work.
>
> Ian
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: structure packing
  2009-05-21 14:39 ` Mohamed Shafi
@ 2009-05-22  6:39   ` Ian Lance Taylor
  2009-05-22  8:01     ` Mohamed Shafi
  0 siblings, 1 reply; 8+ messages in thread
From: Ian Lance Taylor @ 2009-05-22  6:39 UTC (permalink / raw)
  To: Mohamed Shafi; +Cc: gcc-help, Rohit Arul Raj

Mohamed Shafi <shafitvm@gmail.com> writes:

> The below code is compiled using a private port based on GCC 4.1.1.
>
> struct data {
>      int wdata;
>      int rdata;
>  };// __attribute__((__packed__));
>
> typedef struct data data;
> #define data_p (*(volatile data *)(0))
>
> int main(void)
> {
>   data_p.wdata = data_p.rdata;
> }
>
> For the above source code without the 'packed' attribute the assembly
> code is generated with word-aligned access. But with packed attribute
> enabled the assembly code is generated with byte access. When i looked
> into x86 compiler i find that the assembly code generated is same
> irrespective of whether the attribute is provided or not.

I don't see this.  When I compile the above test case (i.e., the struct
is not packed) on x86, I see word accesses.

> In case,
> 1) if the packing is enabled and all the data elements inside the
> struct are by default word-aligned (all the 32bit integers) is it
> possible to generate word-aligned assembly code?

No.  The packed attribute tells the compiler that the struct may be
misaligned.

> 2) Packing is enabled for a structure with different data elements.
>
> i.e.
> struct data {
>      int wdata;
>     char t;
>      int rdata;
>  } __attribute__((__packed__));
>
> Is it possible to generate code like:
> wdata -> word aligned access.
> rdata -> byte aligned access.

No.  You could try putting a packed struct inside the unpacked struct,
though; I don't know whether or not that would work.

Ian

^ permalink raw reply	[flat|nested] 8+ messages in thread

* structure packing
       [not found] <ba0bd44d0905210723n5e6e85f5rea8b2b52c381d5d9@mail.gmail.com>
@ 2009-05-21 14:39 ` Mohamed Shafi
  2009-05-22  6:39   ` Ian Lance Taylor
  0 siblings, 1 reply; 8+ messages in thread
From: Mohamed Shafi @ 2009-05-21 14:39 UTC (permalink / raw)
  To: gcc-help; +Cc: Rohit Arul Raj

Hello all,

The below code is compiled using a private port based on GCC 4.1.1.

struct data {
     int wdata;
     int rdata;
 };// __attribute__((__packed__));

typedef struct data data;
#define data_p (*(volatile data *)(0))

int main(void)
{
  data_p.wdata = data_p.rdata;
}

For the above source code without the 'packed' attribute the assembly
code is generated with word-aligned access. But with packed attribute
enabled the assembly code is generated with byte access. When i looked
into x86 compiler i find that the assembly code generated is same
irrespective of whether the attribute is provided or not.
I am assuming that this happens because when 'packed' attribute is
provided the compiler assumes that there is no alignment to natural
boundary and so produces code for byte access.  Am i right?

In case,
1) if the packing is enabled and all the data elements inside the
struct are by default word-aligned (all the 32bit integers) is it
possible to generate word-aligned assembly code?

2) Packing is enabled for a structure with different data elements.

i.e.
struct data {
     int wdata;
    char t;
     int rdata;
 } __attribute__((__packed__));

Is it possible to generate code like:
wdata -> word aligned access.
rdata -> byte aligned access.

Regards,
Shafi

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: structure packing.
@ 2008-10-20  7:52 Duft Markus
  0 siblings, 0 replies; 8+ messages in thread
From: Duft Markus @ 2008-10-20  7:52 UTC (permalink / raw)
  To: gcc-help

> 
> Hi!
> 
> I have a strange problem with some of my source code. I have something
> similar as the small test case below, which I compile with multiple
> different compilers (and compiler versions), including visual c++
2003,
> 2005 and 2008 and GCC 3.3 and 4.2.
> 
> It seems that gcc 4.2 makes some troubles ;) could please somebody
take
> a look at the things below, and tell me wether I'm just blind and
dumb,
> or there is a problem with gcc?

Some more testing revealed that using the gcc_struct attribute
additionally, makes it work.... is there any explanation for this? I
thought gcc_struct would be the default? (btw. I _am_ on windows, but
using interix, which I think should be pretty much unix, and nearly no
windows...).

Cheers, Markus

> 
> Thanks in advance, Cheers, Markus
> 
> mduft build $ cat zz.c
> #include <stdio.h>
> 
> typedef struct __attribute__((packed, aligned(2))) {
> 	unsigned int a;
> 	unsigned short b;
> 	unsigned int c;
> } teststruct;
> 
> int main(void) {
> 	printf("uint: %d, ushort: %d, struct: %d (should be %d)\n",
> 		sizeof(unsigned int), sizeof(unsigned short),
> sizeof(teststruct),
> 		(sizeof(unsigned int) * 2) + sizeof(unsigned short));
> }
> mduft build $ gcc zz.c
> mduft build $ ./a.out
> uint: 4, ushort: 2, struct: 12 (should be 10)
> 
> mduft build $ gcc -v
> Using built-in specs.
> Target: i586-pc-interix6.0
> Configured with: /opt/gentoo.system/var/tmp/portage/sys-devel/gcc-
> 4.2.4-r00.1/work/gcc-4.2.4/configure --prefix=/opt/gentoo.system/usr
--
> bindir=/opt/gentoo.system/usr/i586-pc-interix6.0/gcc-bin/4.2.4 --
> includedir=/opt/gentoo.system/usr/lib/gcc/i586-pc-
> interix6.0/4.2.4/include --datadir=/opt/gentoo.system/usr/share/gcc-
> data/i586-pc-interix6.0/4.2.4 --
> mandir=/opt/gentoo.system/usr/share/gcc-data/i586-pc-
> interix6.0/4.2.4/man --infodir=/opt/gentoo.system/usr/share/gcc-
> data/i586-pc-interix6.0/4.2.4/info --with-gxx-include-
> dir=/opt/gentoo.system/usr/lib/gcc/i586-pc-
> interix6.0/4.2.4/include/g++-v4 --host=i586-pc-interix6.0
--build=i586-
> pc-interix6.0 --disable-altivec --disable-nls --with-system-zlib --
> disable-checking --disable-werror --enable-secureplt
--disable-multilib
> --disable-libmudflap --disable-libssp --disable-libgcj --enable-
> languages=c,c++,treelang --enable-shared --enable-threads=posix
--with-
> local-prefix=/opt/gentoo.system/usr
> Thread model: posix
> gcc version 4.2.4 (Gentoo 4.2.4-r00.1 p1.0)
> 
> mduft build $ /opt/gcc.3.3/bin/gcc zz.c
> mduft build $ ./a.out
> uint: 4, ushort: 2, struct: 10 (should be 10)
> mduft build $

^ permalink raw reply	[flat|nested] 8+ messages in thread

* structure packing.
@ 2008-10-20  7:33 Duft Markus
  0 siblings, 0 replies; 8+ messages in thread
From: Duft Markus @ 2008-10-20  7:33 UTC (permalink / raw)
  To: gcc-help

Hi!

I have a strange problem with some of my source code. I have something
similar as the small test case below, which I compile with multiple
different compilers (and compiler versions), including visual c++ 2003,
2005 and 2008 and GCC 3.3 and 4.2.

It seems that gcc 4.2 makes some troubles ;) could please somebody take
a look at the things below, and tell me wether I'm just blind and dumb,
or there is a problem with gcc?

Thanks in advance, Cheers, Markus

mduft build $ cat zz.c
#include <stdio.h>

typedef struct __attribute__((packed, aligned(2))) {
	unsigned int a;
	unsigned short b;
	unsigned int c;
} teststruct;

int main(void) {
	printf("uint: %d, ushort: %d, struct: %d (should be %d)\n",
		sizeof(unsigned int), sizeof(unsigned short),
sizeof(teststruct),
		(sizeof(unsigned int) * 2) + sizeof(unsigned short));
}
mduft build $ gcc zz.c 
mduft build $ ./a.out 
uint: 4, ushort: 2, struct: 12 (should be 10)

mduft build $ gcc -v
Using built-in specs.
Target: i586-pc-interix6.0
Configured with:
/opt/gentoo.system/var/tmp/portage/sys-devel/gcc-4.2.4-r00.1/work/gcc-4.
2.4/configure --prefix=/opt/gentoo.system/usr
--bindir=/opt/gentoo.system/usr/i586-pc-interix6.0/gcc-bin/4.2.4
--includedir=/opt/gentoo.system/usr/lib/gcc/i586-pc-interix6.0/4.2.4/inc
lude
--datadir=/opt/gentoo.system/usr/share/gcc-data/i586-pc-interix6.0/4.2.4
--mandir=/opt/gentoo.system/usr/share/gcc-data/i586-pc-interix6.0/4.2.4/
man
--infodir=/opt/gentoo.system/usr/share/gcc-data/i586-pc-interix6.0/4.2.4
/info
--with-gxx-include-dir=/opt/gentoo.system/usr/lib/gcc/i586-pc-interix6.0
/4.2.4/include/g++-v4 --host=i586-pc-interix6.0
--build=i586-pc-interix6.0 --disable-altivec --disable-nls
--with-system-zlib --disable-checking --disable-werror
--enable-secureplt --disable-multilib --disable-libmudflap
--disable-libssp --disable-libgcj --enable-languages=c,c++,treelang
--enable-shared --enable-threads=posix
--with-local-prefix=/opt/gentoo.system/usr
Thread model: posix
gcc version 4.2.4 (Gentoo 4.2.4-r00.1 p1.0)

mduft build $ /opt/gcc.3.3/bin/gcc zz.c 
mduft build $ ./a.out 
uint: 4, ushort: 2, struct: 10 (should be 10)
mduft build $

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-01-16 11:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-16 10:45 structure packing vijay nag
2014-01-16 11:34 ` David Brown
     [not found] <ba0bd44d0905210723n5e6e85f5rea8b2b52c381d5d9@mail.gmail.com>
2009-05-21 14:39 ` Mohamed Shafi
2009-05-22  6:39   ` Ian Lance Taylor
2009-05-22  8:01     ` Mohamed Shafi
2009-05-22 13:51       ` Ian Lance Taylor
  -- strict thread matches above, loose matches on Subject: below --
2008-10-20  7:52 Duft Markus
2008-10-20  7:33 Duft Markus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).