Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Structure padding.

Reply
Thread Tools

Structure padding.

 
 
Amarendra
Guest
Posts: n/a
 
      06-21-2004
Folks,

This structure padding issue is bothering me now, could
not locate a satisfactory answer on clc, so here it goes...

I have a structure, given below:
typedef struct {
int flag;
char keys[3][9];
char padding[??];
} foo;

I need to fill in the size of padding array here so as to
make the entire structure size a multiple of 8. Is there
a way in which I can calculate the padding ? This structure
will be used on AIX 5.* and RHL.

Thanks in advance.

Cheers,
Amar

--
If you don't want to succeed, nobody will try to stop you.
 
Reply With Quote
 
 
 
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      06-21-2004

On Mon, 21 Jun 2004, Amarendra wrote:
>
> This structure padding issue is bothering me now, could
> not locate a satisfactory answer on clc, so here it goes...
>
> I have a structure, given below:
> typedef struct {
> int flag;
> char keys[3][9];
> char padding[??];
> } foo;
>
> I need to fill in the size of padding array here so as to
> make the entire structure size a multiple of 8. Is there
> a way in which I can calculate the padding ?


Obviously not. Any compiler is perfectly capable of padding
your structure to make it a multiple of 8 bytes, minus 1, and
there's nothing you can do about it, from the Standard's point
of view.
In practice, you'll probably be able to get away with a
system-specific solution such as

#define PAD_EIGHT(siz) ((siz) - (siz)/8*
struct half_foo {
int flag;
char keys[3][9];
};
typedef struct {
int flag;
char keys[3][9];
char padding[PAD_EIGHT(sizeof (struct half_foo))];
} foo;

or (even less portably but much clearer to the next guy)

typedef struct {
int flag;
char keys[3][9];
char padding[1]; /* Pad to a multiple of 8 bytes */
} foo;

In practice, of course, it doesn't matter at all what the size
of your structure is: let the computer worry about it. Most
compilers have some kind of "optimize for speed/space" flag
that will make your code run quickly no matter what the size of
some little structure is.

-Arthur
 
Reply With Quote
 
 
 
 
Jens.Toerring@physik.fu-berlin.de
Guest
Posts: n/a
 
      06-21-2004
Amarendra <(E-Mail Removed)> wrote:
> This structure padding issue is bothering me now, could
> not locate a satisfactory answer on clc, so here it goes...


> I have a structure, given below:
> typedef struct {
> int flag;
> char keys[3][9];
> char padding[??];
> } foo;


> I need to fill in the size of padding array here so as to
> make the entire structure size a multiple of 8. Is there
> a way in which I can calculate the padding ? This structure
> will be used on AIX 5.* and RHL.


That's something clc can't answer because there is no requirement
on how much padding a compiler is supposed to use by the C standard.
It obviously will differ between different architectures, but also
compilers and maybe even different compiler versions. The first
question that comes to mind is why you need the structures size to
be a multiple of 8?

<OT>
You could write a script that writes C programs that create structures
like the above with ever increasing lengths for the padding array and
which then write out the sizeof the structure. The script compiles
and runs these programs until the structures size is a multiple of 8
and you use that length of the padding array in the real program (maybe
by writing the value into an include file to be included by the real
program). Shouldn't be too hard to do with a reasonably short script.
</OT>
Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de
\__________________________ http://www.toerring.de
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      06-21-2004
In article <(E-Mail Removed) >
Amarendra <(E-Mail Removed)> writes:
>This structure padding issue is bothering me now, could
>not locate a satisfactory answer on clc, so here it goes...
>
>I have a structure, given below:
> typedef struct {
> int flag;
> char keys[3][9];
> char padding[??];
> } foo;
>
>I need to fill in the size of padding array here so as to
>make the entire structure size a multiple of 8. Is there
>a way in which I can calculate the padding ? ...


The answer is no -- and yes.

There is no way to do it "in one pass", as it were, but you can
still do it by generating the declaration at runtime, then (after
this runtime has finished) use that declaration at a later
compile-time.

This does make some assumptions, such as "a later invocation of
the compiler will use the same layout as an earlier invocation of
the compiler" -- which should be true unless you wait too long (so
that the compiler has been replaced with a later version), or change
the set of flags you pass to the compiler. It also makes the build
process for your software (much) more complicated: instead of just
"compile all this C code", you have to do this, in sequence:

- compile C code to generate the structure
- run the program, putting the struct declaration into a file for
use in the next step
- compile the code that uses the newly-created declaration

It is not clear to me why you want an explicit "padding blob". In
my experience, most people who do that are trying to make the
internal C structure layout meet some external file format -- which
is often a mistake, as it is sometimes quite difficult to get an
internal data structure to match external constraints at all, and
often quite easy to make the input and output operations translate
between "external" and "internal" formats. The translation code
can either assume or force 8-bit "regular bytes" (octets) using "C
bytes" (unsigned char), which are usually exactly 8 bits, and are
never fewer than 8 bits. The "externalized" octets can be matched
to the desired layout completely portably.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
Thomas Matthews
Guest
Posts: n/a
 
      06-21-2004
Amarendra wrote:

> Folks,
>
> This structure padding issue is bothering me now, could
> not locate a satisfactory answer on clc, so here it goes...
>
> I have a structure, given below:
> typedef struct {
> int flag;
> char keys[3][9];
> char padding[??];
> } foo;
>
> I need to fill in the size of padding array here so as to
> make the entire structure size a multiple of 8. Is there
> a way in which I can calculate the padding ? This structure
> will be used on AIX 5.* and RHL.
>
> Thanks in advance.
>
> Cheers,
> Amar
>
> --
> If you don't want to succeed, nobody will try to stop you.


In these cases, I revert to assembly language. Many assembly
languages provide compiler directives to align data fields
to a given boundary. I then "export" the symbol and use
"extern" in the C language.

--
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.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

 
Reply With Quote
 
Arthur J. O'Dwyer
Guest
Posts: n/a
 
      06-21-2004

On Mon, 21 Jun 2004 (E-Mail Removed)-berlin.de wrote:
>
> Amarendra <(E-Mail Removed)> wrote:
> > I have a structure, given below:
> > typedef struct {
> > int flag;
> > char keys[3][9];
> > char padding[??];
> > } foo;
> >
> > I need to fill in the size of padding array here so as to
> > make the entire structure size a multiple of 8. Is there
> > a way in which I can calculate the padding ? This structure
> > will be used on AIX 5.* and RHL.


> <OT>
> You could write a script that writes C programs that create structures
> like the above with ever increasing lengths for the padding array and
> which then write out the sizeof the structure. The script compiles
> and runs these programs until the structures size is a multiple of 8
> and you use that length of the padding array in the real program (maybe
> by writing the value into an include file to be included by the real
> program). Shouldn't be too hard to do with a reasonably short script.
> </OT>


Hey, good idea!

#include <stdio.h>

#define PADSIZE(n) (sizeof(struct {int flag; char keys[9][3]; \
char pad[n];}))
#define PADOK(n) (PADSIZE(n)%8==0)
#define PAD (PADOK(1)? 1: PADOK(2)? 2: PADOK(3)? 3: PADOK(4)? 4: \
PADOK(5)? 5: PADOK(6)? 6: PADOK(7)? 7: PADOK(? 8: -1)

typedef struct {
int flag;
char keys[9][3];
char padding[PAD];
} foo;

(Naturally, the OP should not use this method. Nor should anyone else.)

-Arthur
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      06-21-2004
Amarendra wrote:
> Folks,
>
> This structure padding issue is bothering me now, could
> not locate a satisfactory answer on clc, so here it goes...
>
> I have a structure, given below:
> typedef struct {
> int flag;
> char keys[3][9];
> char padding[??];
> } foo;
>
> I need to fill in the size of padding array here so as to
> make the entire structure size a multiple of 8. Is there
> a way in which I can calculate the padding ? This structure
> will be used on AIX 5.* and RHL.


Others have pointed out that there's no completely
guaranteed solution (because the compiler may add more
padding bytes you have no control over). Others have
also offered some non-guaranteed solutions involving
macros and/or two passes. Here's a variation that
might be simpler, if you can tolerate having the padding
appear "after" the struct rather than inside it:

typedef union { /* not struct */
struct foo_data {
int flag;
char keys[3][9];
} payload;
char overlay[(sizeof(struct foo_data) + 7) / 8];
} foo;

A disadvantage is that you need to write things like
`fooptr->payload.flag' instead of `fooptr->flag'. And,
of course, the compiler might still decide to make the
union larger than you want, and this might destroy the
multiple-of-eight size.

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      06-21-2004
In <(E-Mail Removed) > (E-Mail Removed) (Amarendra) writes:

>This structure padding issue is bothering me now, could
>not locate a satisfactory answer on clc, so here it goes...
>
>I have a structure, given below:
> typedef struct {
> int flag;
> char keys[3][9];
> char padding[??];
> } foo;
>
>I need to fill in the size of padding array here so as to
>make the entire structure size a multiple of 8. Is there
>a way in which I can calculate the padding ? This structure
>will be used on AIX 5.* and RHL.


Yes. It's not strictly guaranteed to work (it will fail if the struct
needs to be aligned to multiples of something greater than 8 or that is
not a power of two) and, in theory, the compiler may add some padding of
its own at the end, but in practice you can calculate the padding if the
compiler is happy with the idea of the structure size being a multiple of
8. In the worst case you may have to add 8 bytes of padding, because
you can't have arrays of size 0. Needless to say, the padding may
differ between implementations (but this is transparent to the source
code).

There is more than way of doing it, but I prefer the one that completely
virtualises the struct definition, at the expense of declaring an
auxiliary structure, mirroring the real one, first:

fangorn:~/tmp 155> cat test.c
#include <stdio.h>
#include <assert.h>
#include <stddef.h>

#define ALIGN 8

struct foo_aux {
int flag;
char keys[3][9];
char padding;
};

struct foo {
int flag;
char keys[3][9];
char padding[ALIGN - offsetof(struct foo_aux, padding) % ALIGN];
};

int main()
{
assert(offsetof(struct foo_aux, padding) == offsetof(struct foo, padding));
assert(sizeof(struct foo) % ALIGN == 0);
printf("%d\n", (int)sizeof(struct foo));
return 0;
}
fangorn:~/tmp 156> gcc test.c
fangorn:~/tmp 157> ./a.out
32

The catch is that both struct definitions must be kept in sync, when
changes are made. This is actually tested by the first assert. If the
second assert fails, there is nothing you can do: the compiler is not
happy with a structure size that is a multiple of 8.

There is a way to automatically keep the two structures in sync, but I'm
not very fond of it: put the common part of the two declarations in a
separate file and include it. Change that file when you need to modify
the structure definition. It's a readability vs maintenability tradeoff.

fangorn:~/tmp 166> cat struct_foo.c
int flag;
char keys[3][9];
fangorn:~/tmp 167> cat test.c
#include <stdio.h>
#include <assert.h>
#include <stddef.h>

#define ALIGN 8

struct foo_aux {
#include "struct_foo.c"
char padding;
};

struct foo {
#include "struct_foo.c"
char padding[ALIGN - offsetof(struct foo_aux, padding) % ALIGN];
};

int main()
{
assert(sizeof(struct foo) % ALIGN == 0);
printf("%d\n", (int)sizeof(struct foo));
return 0;
}
fangorn:~/tmp 168> gcc test.c
fangorn:~/tmp 169> ./a.out
32

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
Dan Pop
Guest
Posts: n/a
 
      06-21-2004
In <(E-Mail Removed)> Eric Sosman <(E-Mail Removed)> writes:

>Amarendra wrote:
>> This structure padding issue is bothering me now, could
>> not locate a satisfactory answer on clc, so here it goes...
>>
>> I have a structure, given below:
>> typedef struct {
>> int flag;
>> char keys[3][9];
>> char padding[??];
>> } foo;
>>
>> I need to fill in the size of padding array here so as to
>> make the entire structure size a multiple of 8. Is there
>> a way in which I can calculate the padding ? This structure
>> will be used on AIX 5.* and RHL.

>
> Others have pointed out that there's no completely
>guaranteed solution (because the compiler may add more
>padding bytes you have no control over). Others have
>also offered some non-guaranteed solutions involving
>macros and/or two passes. Here's a variation that
>might be simpler, if you can tolerate having the padding
>appear "after" the struct rather than inside it:
>
> typedef union { /* not struct */
> struct foo_data {
> int flag;
> char keys[3][9];
> } payload;
> char overlay[(sizeof(struct foo_data) + 7) / 8];
> } foo;
>
>A disadvantage is that you need to write things like
>`fooptr->payload.flag' instead of `fooptr->flag'.


Another "disadvantage" is that you're grossly miscalculating the size of
overlay, which is 8 times smaller than it should be! No point in
dividing by 8 if you don't multiply back by 8

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: (E-Mail Removed)
 
Reply With Quote
 
John Ilves
Guest
Posts: n/a
 
      06-21-2004
This seems to work for me (with gcc on linux):

#include <stdio.h>

struct foo
{
int flag : 4; /* force 32 bit */
char keys[3][9]; /* 3 * 9 == 27 */
int _pad_ : 1; /* 4 + 27 + 1 == 32, 32 % 8 == 0 */
};

int
main()
{
printf( "struct foo is %d bytes, and %s divisible by 8\n",
sizeof(struct foo),
sizeof(struct foo) % 8 ? "is not" : "is" );

return 0;
}

Hope it helps,
John

PS Nice email address.


Amarendra wrote:
> Folks,
>
> This structure padding issue is bothering me now, could
> not locate a satisfactory answer on clc, so here it goes...
>
> I have a structure, given below:
> typedef struct {
> int flag;
> char keys[3][9];
> char padding[??];
> } foo;
>
> I need to fill in the size of padding array here so as to
> make the entire structure size a multiple of 8. Is there
> a way in which I can calculate the padding ? This structure
> will be used on AIX 5.* and RHL.
>
> Thanks in advance.
>
> Cheers,
> Amar
>
> --
> If you don't want to succeed, nobody will try to stop you.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Difference between c structure and c++ structure raghunandan_1081@yahoo.com C++ 9 11-11-2011 07:34 AM
How to read a Structure from a matlab file to a structure in Vc++ 2003 meisterbartsch C++ 2 06-12-2007 08:47 PM
Memory allocation in Structure to Structure pra_ramli@rediffmail.com C++ 2 03-09-2006 05:51 AM
Copy String structure "A" to string structure "B" Leo Nunez C Programming 3 02-09-2005 05:14 AM
Pointers to structure and array of structure. Excluded_Middle C Programming 4 10-26-2004 05:39 AM



Advertisments