structure padding

R

ramu

Hi all,
I understand that some compilers pad some bytes to the
aggregate data types in order to access the members of the aggregate
data types(i.e. structure) fast. This depends on the architectures.
Some architectures cannot access the data which will be stored on the
odd addresses or they may find difficult to access it. This is the
reason for padding extra bytes.

Now consider the following structure:

struct {
int i; // 4 bytes
char c; // 1 byte
char b; // 1 byte
}a;

Now consider the memory representation for this structure:

----------------------------- Memory locations
i 0
-----------------------------
i 1
-----------------------------
i 2
------------------------------
i 3
-------------------------------
c 4
--------------------------------
b 5
--------------------------------
padding 6
---------------------------------
padding 7
---------------------------------

The size of this strucutre will be 8bytes after padding.
The first 4 memory locations(0 to 3) are allocated for int i;
The next byte(4) is allocated for char c;
the next byte(5) is allocated for char b;

Now my doubt is , does not the processor find it difficult to access
the value of the variable which is stored in odd memory location(ie.
5)? can anyone elaborate on this?

Regards
 
V

Vladimir S. Oka

ramu said:
Hi all,
I understand that some compilers pad some bytes to the
aggregate data types in order to access the members of the aggregate
data types(i.e. structure) fast. This depends on the architectures.
Some architectures cannot access the data which will be stored on the
odd addresses or they may find difficult to access it. This is the
reason for padding extra bytes.

This is off topic here.
Now consider the following structure:

struct {
int i; // 4 bytes
char c; // 1 byte
char b; // 1 byte
}a;

Now consider the memory representation for this structure:

< snip >

<OT>
If such a padding is to take place, it's more likely that both `c` and
`d` will `occupy` a 4-byte memory block, or whichever block is
convenient for the implementation.
</OT>

Cheers

Vladimir
 
S

santosh

In 32 - bit processors , Each bus cycle will access the 32 - bit data
from memory. For reading variable b, first the processor reads the
entire 32 bit word which includes b, c and the padded data.

This is the reason why padding is required. (it is required for
allignment).
 
N

Nelu

santosh said:
In 32 - bit processors , Each bus cycle will access the 32 - bit data
from memory. For reading variable b, first the processor reads the
entire 32 bit word which includes b, c and the padded data.

This is the reason why padding is required. (it is required for
allignment).
Before posting again, please read:
http://cfaj.freeshell.org/google/

Thank you.
 
R

Rod Pemberton

ramu said:
Hi all,
I understand that some compilers pad some bytes to the
aggregate data types in order to access the members of the aggregate
data types(i.e. structure) fast. This depends on the architectures.
Some architectures cannot access the data which will be stored on the
odd addresses or they may find difficult to access it. This is the
reason for padding extra bytes.

Now consider the following structure:

struct {
int i; // 4 bytes
char c; // 1 byte
char b; // 1 byte
}a;

Okay. Layout can be compiler specific.
Now my doubt is , does not the processor find it difficult to access
the value of the variable which is stored in odd memory location(ie.
5)? can anyone elaborate on this?

No idea. The code generate by DJGPP and OW are radically different. You'll
need to study the disassembly.


If you want to see the exact layout of a structure with different packings,
you can play with this code:

#include <stdio.h>

// Works for DJGPP 2.03 and OW 1.3
#ifdef __DJGPP__
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
#endif

// default alignment
struct {
unsigned int i;
unsigned char c;
unsigned long a;
unsigned short e;
unsigned char b;
} s0;

#pragma pack(push,1)
struct {
unsigned int i;
unsigned char c;
unsigned long a;
unsigned short e;
unsigned char b;
} s1;
#pragma pack(pop)

#pragma pack(push,2)
struct {
unsigned int i;
unsigned char c;
unsigned long a;
unsigned short e;
unsigned char b;
} s2;
#pragma pack(pop)

#pragma pack(push,4)
struct {
unsigned int i;
unsigned char c;
unsigned long a;
unsigned short e;
unsigned char b;
} s3;
#pragma pack(pop)


void print_s(unsigned char *s, int size)
{
int i;

printf("%d ",size);
for(i=0;i<size;i++)
{
printf("%02x ",s);
}
printf("\n");
}

int main(void)
{
s0.i=(unsigned int)0xF0F1F2F3; // cast in case 16 not 32
s0.a=(unsigned long)0xE0E1E2E3; // cast in case 16 not 32
s0.e=(unsigned short)0xD0D1D2D3; // cast in case 16 not 32
s0.c=0xFC;
s0.b=0xFE;

s1.i=(unsigned int)0xF0F1F2F3; // cast in case 16 not 32
s1.a=(unsigned long)0xE0E1E2E3; // cast in case 16 not 32
s1.e=(unsigned short)0xD0D1D2D3; // cast in case 16 not 32
s1.c=0xFC;
s1.b=0xFE;

s2.i=(unsigned int)0xF0F1F2F3; // cast in case 16 not 32
s2.a=(unsigned long)0xE0E1E2E3; // cast in case 16 not 32
s2.e=(unsigned short)0xD0D1D2D3; // cast in case 16 not 32
s2.c=0xFC;
s2.b=0xFE;

s3.i=(unsigned int)0xF0F1F2F3; // cast in case 16 not 32
s3.a=(unsigned long)0xE0E1E2E3; // cast in case 16 not 32
s3.e=(unsigned short)0xD0D1D2D3; // cast in case 16 not 32
s3.c=0xFC;
s3.b=0xFE;

printf("s0 ");
print_s((unsigned char *)&s0,sizeof(s0));
printf("s1 ");
print_s((unsigned char *)&s1,sizeof(s1));
printf("s2 ");
print_s((unsigned char *)&s2,sizeof(s2));
printf("s3 ");
print_s((unsigned char *)&s3,sizeof(s3));

return(0);
}


Rod Pemberton
 
I

Ian Collins

santosh said:
In 32 - bit processors , Each bus cycle will access the 32 - bit data
from memory. For reading variable b, first the processor reads the
entire 32 bit word which includes b, c and the padded data.

This is the reason why padding is required. (it is required for
allignment).
It isn't required (but is desirable) on processors that can perform
misaligned access.

Alignment is very implementation specific and can be a compatibility
headache if code assumes a certain alignment.
 
V

Vladimir S. Oka

santosh said:
I dint know that.

I believe it also says something about top-posting (I corrected yours
here), and possibly even about not quoting signatures.

Cheers

Vladimir
 
R

Robin Haigh

ramu said:
Hi all,
I understand that some compilers pad some bytes to the
aggregate data types in order to access the members of the aggregate
data types(i.e. structure) fast. This depends on the architectures.
Some architectures cannot access the data which will be stored on the
odd addresses or they may find difficult to access it. This is the
reason for padding extra bytes.

Now consider the following structure:

struct {
int i; // 4 bytes
char c; // 1 byte
char b; // 1 byte
}a;

[snip]

The size of this strucutre will be 8bytes after padding.
The first 4 memory locations(0 to 3) are allocated for int i;
The next byte(4) is allocated for char c;
the next byte(5) is allocated for char b;

Now my doubt is , does not the processor find it difficult to access
the value of the variable which is stored in odd memory location(ie.
5)? can anyone elaborate on this?


Alignment is a problem when objects lie across boundaries, requiring
multiple fetches if they can be fetched at all.

The types which are smaller than a word never straddle a boundary. They
were provided in C so that you can pack more than one item into a word. The
unpacking overhead should be relatively minor, but if you're worried, you
can always store your characters in ints. That's your choice: if you choose
the "packable" type, it's not the compiler's job to change your mind.
 
R

Richard Bos

Vladimir S. Oka said:
This is off topic here.

Not really. That certain types may require alignments, and that
structures may contain padding for that and other reasons, is perfectly
Standard. Which types happen to require padding on a specific
implementation, and how much, that's off topic here. The principle
itself, though, is on topic.
< snip >

<OT>
If such a padding is to take place, it's more likely that both `c` and
`d` will `occupy` a 4-byte memory block, or whichever block is
convenient for the implementation.

Not necessarily. One thing is certain, though: if normal ints aren't
just 4 bytes large, but also require 4-byte alignment, the
implementation must make certain that no ints, including the one in the
second member of an array of these structs, break alignment. Of course
it's possible for the implementation to fudge this in the background by
accessing all struct-member ints as arrays of char, but the best and
perfectly Standard way would be to make the whole struct take 8 bytes: 4
for the int, 1 each for the chars, and 2 for padding to make sure the
next int also ends up on a well-aligned memory address.

Richard
 
V

Vladimir S. Oka

Richard said:
Not really. That certain types may require alignments, and that
structures may contain padding for that and other reasons, is perfectly
Standard. Which types happen to require padding on a specific
implementation, and how much, that's off topic here. The principle
itself, though, is on topic.

Agreed, in principle. ;-)

How OP's query sounded to me, however, was more on the off topic side
of it (it asked about how "difficult" it was for the processor). I
might have missed the point, though (it has happened before ;-) ).
Not necessarily. One thing is certain, though: if normal ints aren't
just 4 bytes large, but also require 4-byte alignment, the
implementation must make certain that no ints, including the one in the
second member of an array of these structs, break alignment. Of course
it's possible for the implementation to fudge this in the background by
accessing all struct-member ints as arrays of char, but the best and
perfectly Standard way would be to make the whole struct take 8 bytes: 4
for the int, 1 each for the chars, and 2 for padding to make sure the
next int also ends up on a well-aligned memory address.

Well, yes, of course. (still OT)

I also said "likely", not "will". It really depends on what one means
by `best` (speed, memory efficiency, ...?), and what
implementation/architecture we're talking about. Going by OP's
specification of a 4-byte int, assuming 4-byte alignment, and
architecture that excels in reading 4-bytes at a time, if we want
speed, compiler is likely to do what I described. If we asked for
memory efficiency, it could do what you suggested. I'm sure one could
come up with an architecture where what I just said is not true, but I
think it'd have to be quite weird (which still does not make either of
us wrong).

Cheers

Vladimir
 
K

Kenneth Brody

ramu wrote:
[...]
Some architectures cannot access the data which will be stored on the
odd addresses or they may find difficult to access it. This is the
reason for padding extra bytes.

Now consider the following structure:

struct {
int i; // 4 bytes
char c; // 1 byte
char b; // 1 byte
}a;

Now consider the memory representation for this structure:

----------------------------- Memory locations
i 0
i 1
i 2
i 3
c 4
b 5
padding 6
padding 7
--------------------------------- [...]
Now my doubt is , does not the processor find it difficult to access
the value of the variable which is stored in odd memory location(ie.
5)? can anyone elaborate on this?

If the processor were unable to access chars at an odd address (highly
unlikely, since this would make accessing character arrays difficult),
then the compiler could always add additional padding:

i: 0, 1, 2, 3
c: 4
pad: 5
d: 6
pad: 7

More likely, it is 16-bit values which require even addresses, and
32-bit values which require either even or multiple-of-4 addresses,
while 8-bit chars can be at any (valid) address.

(Yes, this assumes 8-bit chars. Adjust the above examples as needed
for non-8-bit-char systems.)

Also, note that some architectures may allow no padding at all for
your example, using only 6 bytes for the struct. Still others may
allow it but incur a speed penalty for accessing "unaligned" values.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

Rod Pemberton said:
Okay. Layout can be compiler specific.
Now my doubt is , does not the processor find it difficult to access
the value of the variable which is stored in odd memory location(ie.
5)? can anyone elaborate on this?

No idea. The code generate by DJGPP and OW are radically different. You'll
need to study the disassembly.


If you want to see the exact layout of a structure with different packings,
you can play with this code:

#include <stdio.h>

// Works for DJGPP 2.03 and OW 1.3 [...]
#ifdef __DJGPP__
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
#endif

You never use this macro.
// default alignment
struct {
unsigned int i;
unsigned char c;
unsigned long a;
unsigned short e;
unsigned char b;
} s0;

#pragma pack(push,1)
[snip]

"#pragma pack" is non-standard.
 
R

Rod Pemberton

Keith Thompson said:
You never use this macro.

Correct. DJGPP needs it to enable '#pragma pack' and '#pragma push'.
// default alignment
struct {
unsigned int i;
unsigned char c;
unsigned long a;
unsigned short e;
unsigned char b;
} s0;

#pragma pack(push,1)
[snip]

"#pragma pack" is non-standard.

Correct again. All packing methods are non-standard. This is the only
method common to both DJGPP and OpenWATCOM. Both DJGPP and OpenWATCOM have
three methods of packing. '...structures...' or '...struct data...' will
need to be replaced with valid C:

/* DJGPP */
#ifdef __DJGPP__

//DJGPP Method 1
//--------
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
#pragma pack(push,1)
....structures...
#pragma pack(pop)

//DJGPP Method 2
//--------
#define HANDLE_SYSV_PRAGMA 1
#pragma pack(1)
....structures...
#pragma pack()

//DJGPP Method 3
//--------
struct EX
{
...struct.data...
} __attribute__ ((packed));

#endif

/* WATCOM */
#ifdef __WATCOMC__

//WATCOM Method 1
//---------
#pragma pack(push,1)
....structures...
#pragma pack(pop)

//WATCOM Method 2
//--------
#pragma pack(1)
....structures...
#pragma pack(2)

//WATCOM Method 3
//--------
_Packed struct EX
{
...struct.data...
};

#endif


Rod Pemberton
 
R

Rod Pemberton

Keith Thompson said:
Rod Pemberton said:
Keith Thompson said:
#ifdef __DJGPP__
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
#endif

You never use this macro.

Correct. DJGPP needs it to enable '#pragma pack' and '#pragma push'. [...]
#pragma pack(push,1)
[snip]

"#pragma pack" is non-standard.

Correct again. All packing methods are non-standard.
[...]

And therefore off-topic.

Vladimir already said he thought the whole thread was off topic, but
apparently a bunch of people disagree with both of you.

Rod Pemberton
 
R

Richard Bos

Rod Pemberton said:
Keith Thompson said:
Rod Pemberton said:
Correct again. All packing methods are non-standard.
[...]

And therefore off-topic.

Vladimir already said he thought the whole thread was off topic, but
apparently a bunch of people disagree with both of you.

Well, yes. I disagree that the _whole_ thread is off topic. The mere
possibility of packing bytes is ISO Standard C. Any implementation-
specific ways of munging them is not, though, and therefore your DJGPP-
and-Watcom-only solution _is_ off topic.

Richard
 
R

Rod Pemberton

Richard Bos said:
Rod Pemberton said:
Keith Thompson said:
Correct again. All packing methods are non-standard.
[...]

And therefore off-topic.

Vladimir already said he thought the whole thread was off topic, but
apparently a bunch of people disagree with both of you.

Well, yes. I disagree that the _whole_ thread is off topic. The mere
possibility of packing bytes is ISO Standard C. Any implementation-
specific ways of munging them is not, though, and therefore your DJGPP-
and-Watcom-only solution _is_ off topic.

A) Implementation extensions to C are still C. C is not a static language.
Go study the history of the development of C from an interpreted typeless
language similar to FORTH. Go find out why operators like '=>>', '=+' were
changed to '>>=', '+=' and then come back me and try to claim that the only
C is specification X,Y, or Z.

B) One can't offer a solution without a request. I gifted a useful code
sample out of generosity to one who is learning about packing. Go back and
reread my post. If you can't comprehend _that_ from my post, you shouldn't
be reading.

C) It amazes me that there are so many people _here_ who incessantly whine
about things that are _beyond_ their control, like: judgemental off-topic
posts, top posting, cutting reply signatures. The 'perceived constraints'
that you experience are _you're_ problem. Not mine. Honestly, whining
about these things reminds me of the bickering of immature little children.
Keep it to yourself and learn to deal with it.


Rod Pemberton
 
C

CBFalconer

Rod said:
.... snip ...

C) It amazes me that there are so many people _here_ who incessantly
whine about things that are _beyond_ their control, like: judgemental
off-topic posts, top posting, cutting reply signatures. The
'perceived constraints' that you experience are _you're_ problem.
Not mine. Honestly, whining about these things reminds me of the
bickering of immature little children. Keep it to yourself and learn
to deal with it.

However the whining bickering immature children often grow up into
useful adults, provided they are corrected when whining, bickering,
or otherwise acting immature. Here we can only identify the
children by their immature actions, such as top-posting, omitting
context, chopping off attributions, failure to snip.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
 
K

Keith Thompson

Rod Pemberton said:
C) It amazes me that there are so many people _here_ who incessantly whine
about things that are _beyond_ their control, like: judgemental off-topic
posts, top posting, cutting reply signatures. The 'perceived constraints'
that you experience are _you're_ problem. Not mine. Honestly, whining
about these things reminds me of the bickering of immature little children.
Keep it to yourself and learn to deal with it.

Um, no.

There are very good reasons why we try to encourage people to follow
some simple posting guidelines here. Jack Klein did an excellent job
of explaining those reasons. Please read this:

<http://groups.google.com/group/comp.lang.c/msg/1460ed5b9ad3dae1?hl=en>
 

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

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top