Deep C- struct packing

Once again, from Deep C. The size of structs.

The basic idea is to test the knowledge that sometimes compilers do optimizations on how the structure is situated in memory. According to the pdf, this is because most hardware architectures are optimized for byte sized access, and so compilers generally pad structures and their elements so that they can be accessed in a byte wise manner. Now this may have been true sometime back, and perhaps still true in a statistical majority sense, but with the profusion of mobile computing devices, I suspect new architectures might have a more fine-grained(than word) access. Anyway,that’s marked for future research. Besides, given how much we have shrunk memory, that’s probably not the case for Smartphones and tablet. They probably still use word optimized architectures. I suppose the older (voice calls only) phones had architectures where this was false. I also think other microcontroller based devices like RSA Security code generators, active noise cancelling chips on headphones/earphones etc.. (aka, wherever memory is still a constraint) this would make a difference, and their architectures might not have inefficient access for sub-word memory accesses.

For now, I’ll just go on with the code and a demo here.


#include

struct X { int a; char b; int c;};

int main(void)
{
printf("%zun",sizeof(int));
printf("%zun",sizeof(char));
printf("%zun",sizeof(struct X));

}

And here’s the output with the minimal set of compilation flags.

anand@anand-usb-boot:C [master] $ gcc struct_padding.c -o struct_padding
anand@anand-usb-boot:C [master] $ ./struct_padding 
4
1
12

Now am running a 64-bit machine, but with 32-bit mode.(Am just reverse guessing since it printed 12, but doesn’t matter for our purposes.
As expected the struct is padded to 12 bytes. Instead of the sum of it’s parts, which is 4+1+4 = 9.

Now let’s add the -fpack-struct option to the gcc command.

anand@anand-usb-boot:C [master] $ gcc struct_padding.c -o struct_padding -fpack-struct
anand@anand-usb-boot:C [master] $ ./struct_padding 
4
1
9

Voila, there it is. the size as our mental model says it should be.
Let’s go add another char pointer to the struct

#include

struct X { int a; char b; int c; char *d;};

int main(void)
{
printf("%zun",sizeof(int));
printf("%zun",sizeof(char));
printf("%zun",sizeof(char *));
printf("%zun",sizeof(struct X));

}


Here’s the output with

anand@anand-usb-boot:C [master] $ gcc struct_padding.c -o struct_padding
anand@anand-usb-boot:C [master] $ ./struct_padding 
4
1
8
24

Here’s the output with -fpack-struct:

gcc struct_padding.c -o struct_padding -fpack-struct
anand@anand-usb-boot:C [master] $ ./struct_padding 
4
1
8
17

That 17 with pack-struct is expected. Note that the pointer size is 8 and without pack-struct it pads up from 20 to 24.

Another good link I came across is this

Advertisements

One thought on “Deep C- struct packing

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s