structure padding

S

Stephen Mayes

I this helloworld portable? I am vaguely aware of something called
"structure padding" and wonder if it could affect this program since the
struct only contains chars.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void)
{
struct
{
unsigned char var1[5];
unsigned char var2[6];
unsigned char var3[2];
} var =
{
{'H', 'e', 'l', 'l', 'o'},
{' ', 'W', 'o', 'r', 'l', 'd'},
{'!', '\n'}
};
char varcopy[sizeof(var)];
size_t i;

memcpy (varcopy, &var, sizeof(varcopy));

for (i = 0; i < sizeof(varcopy); i++)
putchar (varcopy);

return EXIT_SUCCESS;
}
 
T

Thomas Matthews

Stephen said:
I this helloworld portable? I am vaguely aware of something called
"structure padding" and wonder if it could affect this program since the
struct only contains chars.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (void)
{
struct
{
unsigned char var1[5];
unsigned char var2[6];
unsigned char var3[2];
} var =
{
{'H', 'e', 'l', 'l', 'o'},
{' ', 'W', 'o', 'r', 'l', 'd'},
{'!', '\n'}
};
char varcopy[sizeof(var)];
size_t i;

memcpy (varcopy, &var, sizeof(varcopy));

for (i = 0; i < sizeof(varcopy); i++)
putchar (varcopy);

return EXIT_SUCCESS;
}


The code is portable. However, the output of
your program may differ depending on platforms
and compiler versions.

The compiler is allowed to insert padding bytes
between members of a class, union or structure.
The value of the padding bytes is undefined.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
S

SM Ryan

# I this helloworld portable? I am vaguely aware of something called
# "structure padding" and wonder if it could affect this program since the
# struct only contains chars.

Some CPU prefer to load and store some types of operands are aligned to
particular byte boundaries. For example ints are often stored word boundaries,
at addresses that are a multiple of 4. Since struct fields are required to
be stored in order, packing them in tightly can put a field at an awkard
boundary. So the compiler can insert unused bytes between fields to
move a later field back to the next desired boundary.

The code will work in the sense that sizeof accounts for padding in the
struct, and memcpy copies padding bytes in sequence with field bytes.
Whether this struct has padding is up to the compiler. It's possible
that it would have 3 padding bytes at the end to bring the size to 16.

# #include <stdio.h>
# #include <stdlib.h>
# #include <string.h>
#
# int main (void)
# {
# struct
# {
# unsigned char var1[5];
# unsigned char var2[6];
# unsigned char var3[2];
# } var =
# {
# {'H', 'e', 'l', 'l', 'o'},
# {' ', 'W', 'o', 'r', 'l', 'd'},
# {'!', '\n'}
# };
# char varcopy[sizeof(var)];
# size_t i;
#
# memcpy (varcopy, &var, sizeof(varcopy));
#
# for (i = 0; i < sizeof(varcopy); i++)
# putchar (varcopy);
#
# return EXIT_SUCCESS;
# }
#
 
E

Eric Sosman

EventHelix.com said:
The following article about structure alignment should help:

http://www.eventhelix.com/RealtimeMantra/ByteAlignmentAndOrdering.htm

Note that the article is not about C, but about "C as
it might be implemented on a certain class of processors."
C is most certainly implemented on processors that do not
fit the article's model, so be sure to read the article as
an example, not as a definition.

Also, the example titled "Actual Structure Definition
Used By the Compiler" is wrong: the `pad3' field is larger
than the article's assumptions say it should be.
 
D

Dave Thompson

I this helloworld portable? I am vaguely aware of something called
"structure padding" and wonder if it could affect this program since the
struct only contains chars.
char varcopy[sizeof(var)];
size_t i;

memcpy (varcopy, &var, sizeof(varcopy));

for (i = 0; i < sizeof(varcopy); i++)
putchar (varcopy);


In practice portable but not quite in theory.

An implementation (compiler) is allowed to add padding after any
member of a struct for any reason, including "today's the third
Tuesday". In practice the only _good_ reason is for alignment, and no
char type in C can require nontrivial alignment, since a pointer to
(flavored) char must be able to access any byte of usable memory.

In the unlikely event there is padding, it is safely copied by memcpy
which accesses memory as unsigned char's. But the implementation
chooses whether to treat plain char like signed or unsigned, and if it
chooses signed that is permitted to have trap representations and the
padding could be such, and if so fetching it (for output) is Undefined
Behavior; but again there is probably no good reason any actual
implementation will screw up.

BTW you could instead just do one call:
fwrite (stdout, varcopy, sizeof varcopy, 1);
Or if you prefer ... varcopy, 1, sizeof varcopy.
Or indeed fwrite from var without copying at all.

- David.Thompson1 at worldnet.att.net
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top