padding mechanism in structures

R

Roman Mashak

Hello, All!

Could you please explain me how is the padding of 'structure' fields is
made?

For example:

struct {
char a1;
int a2;
double a3;
} str;

When I'm checking "sizeof str" in GCC compiler I get the value of size as
16, it means some bytes are padded right?

Thanks!

PS. Or, point me to Inet link, if there is one.

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
M

Mehta Shailendrakumar

see if this helps with sample code attachment
pack
#pragma pack( [ n] )

Specifies packing alignment for structure and union members. Whereas the
packing alignment of structures and unions is set for an entire translation
unit by the /Zp option, the packing alignment is set at the data-declaration
level by the pack pragma. The pragma takes effect at the first structure or
union declaration after the pragma is seen; the pragma has no effect on
definitions.

When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each structure
member after the first is stored on the smaller member type or n-byte
boundaries. If you use #pragma pack without an argument, structure members
are packed to the value specified by /Zp. The default /Zp packing size is
/Zp8.

The compiler also supports the following enhanced syntax:

#pragma pack( [ [ { push | pop}, ] [ identifier, ] ] [ n ] )

This syntax allows you to combine program components into a single
translation unit if the different components use pack pragmas to specify
different packing alignments.

Each occurrence of a pack pragma with a push argument stores the current
packing alignment on an internal compiler stack. The pragma's argument list
is read from left to right. If you use push, the current packing value is
stored. If you provide a value for n, that value becomes the new packing
value. If you specify an identifier, a name of your choosing, the identifier
is associated with the new packing value.

Each occurrence of a pack pragma with a pop argument retrieves the value at
the top of an internal compiler stack and makes that value the new packing
alignment. If you use pop and the internal compiler stack is empty, the
alignment value is that set from the command-line and a warning is issued.
If you use pop and specify a value for n, that value becomes the new packing
value. If you use pop and specify an identifier, all values stored on the
stack are removed from the stack until a matching identifier is found. The
packing value associated with the identifier is also removed from the stack
and the packing value that existed just before the identifier was pushed
becomes the new packing value. If no matching identifier is found, the
packing value set from the command line is used and a level-one warning is
issued. The default packing alignment is 8.

The new, enhanced functionality of the pack pragma allows you to write
header files that ensure that packing values are the same before and after
the header file is encountered:

/* File name: include1.h
*/
#pragma pack( push, enter_include1 )
/* Your include-file code ... */
#pragma pack( pop, enter_include1 )
/* End of include1.h */
In the previous example, the current pack value is associated with the
identifier enter_include1 and pushed, remembered, on entry to the header
file. The pack pragma at the end of the header file removes all intervening
pack values that may have occurred in the header file and removes the pack
value associated with enter_include1. The header file thus ensures that the
pack value is the same before and after the header file.

The new functionality also allows you to use code, such as header files,
that uses pack pragmas to set packing alignments that differ from the
packing value set in your code:

#pragma pack( push, before_include1 )
#include "include1.h"
#pragma pack( pop, before_include1 )
In the previous example, your code is protected from any changes to the
packing value that might occur in include.h.
 
J

Jean-Claude Arbaut

Le 15/06/2005 13:53, dans [email protected], « Roman Mashak »
Hello, All!

Could you please explain me how is the padding of 'structure' fields is
made?

For example:

struct {
char a1;
int a2;
double a3;
} str;

When I'm checking "sizeof str" in GCC compiler I get the value of size as
16, it means some bytes are padded right?

Thanks!

PS. Or, point me to Inet link, if there is one.

With best regards, Roman Mashak. E-mail: (e-mail address removed)

It is probably architecture-dependant (and compiler-dependant), but
probably the double needs 8 bytes alignment, and the int needs 4 bytes, so:

A1 xx xx xx
A2 A2 A2 A2
A3 A3 A3 A3
A3 A3 A3 A3
 
M

Mehta Shailendrakumar

Hello Lawrence,

I have fwded gcc compiler specific info.
Can you suggest portable way to control padding?
Thanks.

Regards,
Shailendra

Lawrence Kirby said:
see if this helps with sample code attachment
pack
#pragma pack( [ n] )

Note that the C language doesn't define a preprocessor directive called
#pragma pack. You compiler may provide one as an extension but you can't
assume that it will exist on other compilers or if it does it will act in
the same way.
 
R

Roman Mashak

Hello, Jean-Claude!
You wrote on Wed, 15 Jun 2005 14:33:52 +0200:

??>> size as 16, it means some bytes are padded right? Thanks! PS. Or,
??>> point me to Inet link, if there is one. With best regards, Roman
??>> Mashak. E-mail: (e-mail address removed)

JCA> It is probably architecture-dependant (and compiler-dependant), but
JCA> probably the double needs 8 bytes alignment, and the int needs 4
JCA> bytes, so:
You mean when allocating memory for srtuct it acts like that (for my example
& GCC compiler, x86 architecture):

'char a1' occupies 1 byte
'int a2' occupies 4 bytes
'double a3' ~ 8 bytes

totally -> 13 bytes, sizeof str = 16 bytes. Seems like 3 bytes are taken
after 'char a1' alignment to int ?

With best regards, Roman Mashak. E-mail: (e-mail address removed)
 
L

Lawrence Kirby

see if this helps with sample code attachment
pack
#pragma pack( [ n] )

Note that the C language doesn't define a preprocessor directive called
#pragma pack. You compiler may provide one as an extension but you can't
assume that it will exist on other compilers or if it does it will act in
the same way.
Specifies packing alignment for structure and union members. Whereas the
packing alignment of structures and unions is set for an entire
translation unit by the /Zp option,

Again, compiler options are inherently compiler specific. Your compiler
might support such an option but you can't assume that others will. In
particular the original poster's compiler probably doesn't.
the packing alignment is set at the
data-declaration level by the pack pragma. The pragma takes effect at
the first structure or union declaration after the pragma is seen; the
pragma has no effect on definitions.

Since neither of these are C language features they aren't particularly
relevant to comp.lang.c. Also the question was more about how padding
works than how you might control it. In standard, portable C you can't.
When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each
structure member after the first is stored on the smaller member type or
n-byte boundaries. If you use #pragma pack without an argument,
structure members are packed to the value specified by /Zp. The default
/Zp packing size is /Zp8.

The compiler also supports the following enhanced syntax:

Again, you mean *your* compiler. Usually the best thing to do with things
like #pragma pack is avoid them studiously since they are inherently
non-portable.

Lawrence
 
J

Jean-Claude Arbaut

Le 15/06/2005 15:44, dans [email protected], « Roman Mashak »
Hello, Jean-Claude!
You wrote on Wed, 15 Jun 2005 14:33:52 +0200:

??>> size as 16, it means some bytes are padded right? Thanks! PS. Or,
??>> point me to Inet link, if there is one. With best regards, Roman
??>> Mashak. E-mail: (e-mail address removed)

JCA> It is probably architecture-dependant (and compiler-dependant), but
JCA> probably the double needs 8 bytes alignment, and the int needs 4
JCA> bytes, so:
You mean when allocating memory for srtuct it acts like that (for my example
& GCC compiler, x86 architecture):

'char a1' occupies 1 byte
'int a2' occupies 4 bytes
'double a3' ~ 8 bytes

totally -> 13 bytes, sizeof str = 16 bytes. Seems like 3 bytes are taken
after 'char a1' alignment to int ?

With best regards, Roman Mashak. E-mail: (e-mail address removed)

Yes that's what I mean: 3 bytes after the char.
Usually variables are aligned "on their size", but you
should make tests or read the documentation of GCC,
or even the ABI for x86. In fact I checked, and with
my gcc/PowerPC, doubles are aligned on 4 bytes only,
whereas the ABI says the natural alignment is 8 bytes.
you can have a look here, but it's for PPC/68K only.
At least it shows what it could resemble on x86.

http://developer.apple.com/documentation/DeveloperTools/Conceptual/PowerPCRu
ntime/Data/chapter_2_section_3.html
 
C

CBFalconer

Mehta said:
.... snip ...

The new functionality also allows you to use code, such as header
files, that uses pack pragmas to set packing alignments that differ
from the packing value set in your code:

#pragma pack( push, before_include1 )
#include "include1.h"
#pragma pack( pop, before_include1 )

In the previous example, your code is protected from any changes
to the packing value that might occur in include.h.

Name: pack.c
pack.c Type: Textpad File (application/x-unknown-content-type-cfile)
Encoding: x-uuencode

Never attach anything to a usenet article, especially a binary.
This is a text only medium.

In addition, pragma is not sanctioned by the standard. From N869:

[#1] A preprocessing directive of the form

# pragma pp-tokens-opt new-line

where the preprocessing token STDC does not immediately
follow pragma in the directive (prior to any macro
replacement)136) causes the implementation to behave in an
implementation-defined manner. The behavior might cause
translation to fail or cause the translator or the resulting
program to behave in a non-conforming manner. Any such
pragma that is not recognized by the implementation is
ignored.
 
L

Lawrence Kirby

Hello Lawrence,

I have fwded gcc compiler specific info.
Can you suggest portable way to control padding?


C provides no method to control padding i.e. alignment of structure
members. If you need an exact format e.g. an external data format then you
shoudln't be trying to map a structure onto it. Indstead treat your
external data as a sequence of bytes and write marshalling./unmarshalling
code to convert between that and an internal representation, e.g. a normal
structure.

In general when you ask about "controlling padding" you're asking the
wrong question, you need to take a higher level look at what it is you are
trying to do.

Lawrence
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Roman said:
Hello, All!

Could you please explain me how is the padding of 'structure' fields is
made?

For example:

struct {
char a1;
int a2;
double a3;
} str;

When I'm checking "sizeof str" in GCC compiler I get the value of size as
16, it means some bytes are padded right?

It could.

It could also mean that
(sizeof(int) == 5) and
(sizeof(double) == 10)

But i doubt it.
Thanks!

PS. Or, point me to Inet link, if there is one.

With best regards, Roman Mashak. E-mail: (e-mail address removed)


- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFCsOSZagVFX4UWr64RAvlJAJwMrq9DGOomZlP2D4oG89XgdlYTagCgiaAl
lgGLNcuefrDQpQC8sa/n5W8=
=hVwW
-----END PGP SIGNATURE-----
 
J

Jack Klein

On Wed, 15 Jun 2005 15:34:34 +0200, "Mehta Shailendrakumar"

Please don't top-post in technical groups. Material you add belongs
after quoted material you are replying to. I have reformatted your
post and added my answer after your question, where they belong.
Lawrence Kirby said:
see if this helps with sample code attachment
pack
#pragma pack( [ n] )

Note that the C language doesn't define a preprocessor directive called
#pragma pack. You compiler may provide one as an extension but you can't
assume that it will exist on other compilers or if it does it will act in
the same way.

Hello Lawrence,

I have fwded gcc compiler specific info.
Can you suggest portable way to control padding?
Thanks.

There is no portable way to control padding. Controlling padding is
not a C language issue, and is not necessary in any event.

And on some architectures attempting to modify padding will result in
hardware traps for misalignment.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,108
Latest member
AlbertEste
Top