Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > struct padding

Reply
Thread Tools

struct padding

 
 
edware
Guest
Posts: n/a
 
      04-25-2006
I want to read header data from a image file,
and I have a struct that represent this header.
But it seems like my compiler pads the data,
resulting that my fread() call won't put the right
things in the right place.

The struct starts like this:

struct header {
char magic[2]; /* 2 bytes */
uint32_t size; /* 4 bytes */
...
};

It seems like my compiler puts two extra
bytes after the magic field, which will
result in a wrong size value.

Is there some standard way to disable the padding?
 
Reply With Quote
 
 
 
 
Andrew Poelstra
Guest
Posts: n/a
 
      04-25-2006
edware wrote:
> I want to read header data from a image file,
> and I have a struct that represent this header.
> But it seems like my compiler pads the data,
> resulting that my fread() call won't put the right
> things in the right place.
>
> The struct starts like this:
>
> struct header {
> char magic[2]; /* 2 bytes */
> uint32_t size; /* 4 bytes */
> ...
> };
>
> It seems like my compiler puts two extra
> bytes after the magic field, which will
> result in a wrong size value.
>
> Is there some standard way to disable the padding?

Well, since the padding itself is compiler-dependant, the answer is
likely no.

Why do you care about padding?
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      04-25-2006
edware wrote:
> I want to read header data from a image file,
> and I have a struct that represent this header.
> But it seems like my compiler pads the data,
> resulting that my fread() call won't put the right
> things in the right place.
>
> The struct starts like this:
>
> struct header {
> char magic[2]; /* 2 bytes */
> uint32_t size; /* 4 bytes */
> ...
> };
>
> It seems like my compiler puts two extra
> bytes after the magic field, which will
> result in a wrong size value.
>
> Is there some standard way to disable the padding?


No.

Your compiler might have an option, if you hardware platform supports it.

--
Ian Collins.
 
Reply With Quote
 
edware
Guest
Posts: n/a
 
      04-25-2006
Andrew Poelstra wrote:
> edware wrote:
>> I want to read header data from a image file,
>> and I have a struct that represent this header.
>> But it seems like my compiler pads the data,
>> resulting that my fread() call won't put the right
>> things in the right place.
>>
>> The struct starts like this:
>>
>> struct header {
>> char magic[2]; /* 2 bytes */
>> uint32_t size; /* 4 bytes */
>> ...
>> };
>>
>> It seems like my compiler puts two extra
>> bytes after the magic field, which will
>> result in a wrong size value.
>>
>> Is there some standard way to disable the padding?

> Well, since the padding itself is compiler-dependant, the answer is
> likely no.
>
> Why do you care about padding?


I care about it because it ruins things for me when I read
the whole structure with a fread() call. Is it better
to read and write each member of the struct individually?

Thanks for the help
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      04-25-2006
edware <> writes:
> I want to read header data from a image file,
> and I have a struct that represent this header.
> But it seems like my compiler pads the data,
> resulting that my fread() call won't put the right
> things in the right place.
>
> The struct starts like this:
>
> struct header {
> char magic[2]; /* 2 bytes */
> uint32_t size; /* 4 bytes */
> ...
> };
>
> It seems like my compiler puts two extra
> bytes after the magic field, which will
> result in a wrong size value.
>
> Is there some standard way to disable the padding?


No. See question 2.12 in the comp.lang.c FAQ, <http://c-faq.com/>.

If the header in the file really contains a 2-byte magic number,
immediately followed by a 4-byte unsigned integer, the best approach
is probably to read it as an array of 6 bytes, then extract the bytes
you want, perhaps using memcpy(). You should also think about byte
ordering; is the size field stored high-order byte first or low-order
byte first?

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Flash Gordon
Guest
Posts: n/a
 
      04-25-2006
Andrew Poelstra wrote:
> edware wrote:
>> I want to read header data from a image file,
>> and I have a struct that represent this header.
>> But it seems like my compiler pads the data,
>> resulting that my fread() call won't put the right
>> things in the right place.
>>
>> The struct starts like this:
>>
>> struct header {
>> char magic[2]; /* 2 bytes */


unsigned char would probably be better. char could be either signed or
unsigned.

>> uint32_t size; /* 4 bytes */
>> ...
>> };
>>
>> It seems like my compiler puts two extra
>> bytes after the magic field, which will
>> result in a wrong size value.
>>
>> Is there some standard way to disable the padding?

> Well, since the padding itself is compiler-dependant, the answer is
> likely no.


The answer is definitely no.

The best method is to read the data a byte at a time and reconstruct the
structures. This also avoids problems with endienness. For strict
portability you should be aware that a byte (and thus a char) may be
more than 8 bits!

> Why do you care about padding?


He already provided that information!
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
 
Reply With Quote
 
Andrew Poelstra
Guest
Posts: n/a
 
      04-25-2006
edware wrote:
> Andrew Poelstra wrote:
>> edware wrote:
>>> I want to read header data from a image file,
>>> and I have a struct that represent this header.
>>> But it seems like my compiler pads the data,
>>> resulting that my fread() call won't put the right
>>> things in the right place.
>>>
>>> The struct starts like this:
>>>
>>> struct header {
>>> char magic[2]; /* 2 bytes */
>>> uint32_t size; /* 4 bytes */
>>> ...
>>> };
>>>
>>> It seems like my compiler puts two extra
>>> bytes after the magic field, which will
>>> result in a wrong size value.
>>>
>>> Is there some standard way to disable the padding?

>> Well, since the padding itself is compiler-dependant, the answer is
>> likely no.
>>
>> Why do you care about padding?

>
> I care about it because it ruins things for me when I read
> the whole structure with a fread() call. Is it better
> to read and write each member of the struct individually?
>
> Thanks for the help


Yes; that way when your struct changes, you won't have to recreate all
your files.

You should also use text files instead of binary for portability reasons.
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      04-26-2006
edware <> wrote:

> Andrew Poelstra wrote:
> > edware wrote:
> >> struct header {
> >> char magic[2]; /* 2 bytes */
> >> uint32_t size; /* 4 bytes */
> >> ...
> >> };
> >>
> >> It seems like my compiler puts two extra
> >> bytes after the magic field, which will
> >> result in a wrong size value.


> > Why do you care about padding?

>
> I care about it because it ruins things for me when I read
> the whole structure with a fread() call. Is it better
> to read and write each member of the struct individually?


Better, yes, since there's no portable way to guarantee that the layout
of a struct in memory matches that of a file record.
The best way to read binary records, though, is often to read the whole
thing into a buffer of unsigned chars using fread(), and then to copy
the values into the desired struct members using shifts and bitwise
operators. To write, do the opposite: use shifts and bitwise ops to move
values of a struct member into the required bytes of an unsigned char
array, and then write the whole thing using fwrite().

Richard
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      04-26-2006
Richard Bos wrote:
> edware <> wrote:
>
>
>>Andrew Poelstra wrote:
>>
>>>edware wrote:
>>>
>>>>struct header {
>>>> char magic[2]; /* 2 bytes */
>>>> uint32_t size; /* 4 bytes */
>>>> ...
>>>>};
>>>>
>>>>It seems like my compiler puts two extra
>>>>bytes after the magic field, which will
>>>>result in a wrong size value.

>
>
>>>Why do you care about padding?

>>
>>I care about it because it ruins things for me when I read
>>the whole structure with a fread() call. Is it better
>>to read and write each member of the struct individually?

>
>
> Better, yes, since there's no portable way to guarantee that the layout
> of a struct in memory matches that of a file record.
> The best way to read binary records, though, is often to read the whole
> thing into a buffer of unsigned chars using fread(), and then to copy
> the values into the desired struct members using shifts and bitwise
> operators. To write, do the opposite: use shifts and bitwise ops to move
> values of a struct member into the required bytes of an unsigned char
> array, and then write the whole thing using fwrite().


An added benefit of this approach is that it becomes
easier to deal with other issues affecting data exchange,
such as endianness, differing notions of how big an `int'
is, different floating-point representations, and so on.
Divorcing the external format from the internal format is
not just about avoiding alignment hassles, but has other
advantages as well.

--
Eric Sosman
lid

 
Reply With Quote
 
Ed Vogel
Guest
Posts: n/a
 
      04-27-2006

"edware" <> wrote in message
news:UKx3g.54370$...
>I want to read header data from a image file,
> and I have a struct that represent this header.
> But it seems like my compiler pads the data,
> resulting that my fread() call won't put the right
> things in the right place.
>
> The struct starts like this:
>
> struct header {
> char magic[2]; /* 2 bytes */
> uint32_t size; /* 4 bytes */
> ...
> };
>
> It seems like my compiler puts two extra
> bytes after the magic field, which will
> result in a wrong size value.
>
> Is there some standard way to disable the padding?


As others have stated, there is no standard way to do this.
However, many compilers have #pragma directives or command
line switches to turn off the padding. While not strictly portable,
this might be a good choice to consider.

Ed


 
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
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
struct padding ??? vikas talwar C Programming 3 05-31-2008 10:06 PM
struct memory padding simonp@nospam.com C++ 11 01-22-2007 10:56 PM
Padding bits and struct assignment Hallvard B Furuseth C Programming 5 12-27-2006 10:19 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments