Viewing the padded bytes

T

The Lost Packet

Chris said:
karthikbalaguru said:
Hi ,

I have the below structure.
struct check_struct{
double a;
char b;
};
My system reports the size of the above structure as 16 bytes.

I understand that there is some padding at the end of the above
structure and hence the size gets calculated to 16 bytes.
But, how to view the data/info that are padded using a debugger
like gdb or visual c++ debugger ?

I used watch windows but, it did not show the padded data .
Any ideas ?

you can try something like the following nasty hack:
___________________________________________________________
#include <stddef.h>
#include <stdio.h>


struct foo {
double m1;
char meof;
};


int main(void) {
char tmp;
struct foo f;

unsigned char* head = (((unsigned char*)&f) +
offsetof(struct foo, meof)) + sizeof(f.meof);

unsigned char* const tail = (unsigned char*)((&f) + 1);

size_t const size = tail - head;

printf("there seems to be %lu bytes of padding at "
"the end of `struct foo'...\n",
(unsigned long int)size);

if (size) {
tmp = head[size - 1];
head[size - 1] = '\0';
printf("pad bytes: %s%c\n\n", head, tmp);
head[size - 1] = tmp;
}

return 0;
}
___________________________________________________________

**** me, I've gorgotten how to read!

--
TLP

- Last night I played a blank tape at full volume. The mime next door
went nuts.

- No, I will not fix your computer.

- Thought: It must be a bitch to write your name in the snow in Arabic...

- Don't sweat the petty things, pet the sweaty things.

- Rice: 1.4 billion Chinese can't all be wrong.

- I'm dreaming of a better world where chickens can cross the road and
not have their motives questioned!

- If you can make a cheesecake you can install a Linux driver from source.

- Don't listen to the do-gooders, condoms are useless. They split,
they leak and they burst. And the human stomach can't handle the impact
of two kilos of cocaine.

- Users who XNA their posts are admitting that their ramblings aren't
worth reading.

- (on Windows) You know why "last known good configuration" almost
never works? Because the last known good configuration was a blank disk.
- Sinister Midget, 15 Jan 2009

*#* Signoff: labo-rat (find / -name \*yourbase\* -exec chown us:us {} \;)
 
B

Barry Schwarz

Hi ,

I have the below structure.
struct check_struct{
double a;
char b;
};
My system reports the size of the above structure as 16 bytes.

I understand that there is some padding at the end of the above
structure and hence the size gets calculated to 16 bytes.

Even if double is 8 bytes on your system, you don't know if the
padding is before b, after b, or both. You could find out with the
offsetof macro but in most cases you shouldn't care.
 
B

Ben Pfaff

Barry Schwarz said:
Even if double is 8 bytes on your system, you don't know if the
padding is before b, after b, or both. You could find out with the
offsetof macro but in most cases you shouldn't care.

It would be quite unusual to insert padding before a member of
type char. Are there any implementations that do this?
 
G

Guest

On 14 Jan, 13:00, "David Webber" <[email protected]>
wrote:
stop programming in C then.

Why?   [Actually I did, many years ago - I do it in C++ these days.]

because it's inherent in the language. A particular implementation
*could* omit the padding but it's under no obligation to do so.

So I would always write the above as
struct check_struct
{
double a;
char b;
char reserved[7];
};

....and fail a code review if it were down to me

Should I care?

yes. Every time you port the program you have to re-write
(or at least examine) EVERY SINGLE STRUCT in the source code!!
In theory every time you upgrade the compiler you have to
do this.

Here lies madness.

I'm guessing you're writing code for toasters.

   Most importantly it reminds me, when I want to make the
structure bigger, not to write

struct check_struct
 {
     double a;
     char b;
     double c;

};

which is truly hideous.  

um. why?

[And anyone who does program in C or C++ should be
close enough to what's going on underneath *never* to write that.]

me! me! I write code like that. I order the fields in what seems
a logical order. Only if I were to write a giant array of
check_structs
would I care about the order. Good grief I just bought a 2G memory
stick for 5UKP. The above wastes 3bytes.

Or unless I were programming a toaster.
 
G

Guest

Ian said:
David said:
On 14 Jan, 13:00, "David Webber" <[email protected]>
wrote:
So I would always write the above as
struct check_struct
{
double a;
char b;
char reserved[7];
};
If you do that you can see the padded bytes.
what happens when they change?
Should I care?    
What happens on a machine with different alignment and or sizes?  What
you have built is unnecessary non-portability.

I don't think that is a concern, considering the cross posts

comp.lang.c, comp.os.linux.development.apps,
microsoft.public.vc.language, comp.os.linux.advocacy

do all linux machines have the same alignment and sizes?
 
T

The Lost Packet

Ian said:
David Webber wrote:
On 14 Jan, 13:00, "David Webber" <[email protected]>
wrote:
So I would always write the above as
struct check_struct
{
double a;
char b;
char reserved[7];
};
If you do that you can see the padded bytes.
what happens when they change?
Should I care?
What happens on a machine with different alignment and or sizes? What
you have built is unnecessary non-portability.
I don't think that is a concern, considering the cross posts

comp.lang.c, comp.os.linux.development.apps,
microsoft.public.vc.language, comp.os.linux.advocacy

do all linux machines have the same alignment and sizes?

no, some of mine are ultraconservative, some are liberal, some are right
wing, there's even a religious one in there (it screams "OH, GOD!!" when
I power it on...)

--
TLP

- Last night I played a blank tape at full volume. The mime next door
went nuts.

- No, I will not fix your computer.

- Thought: It must be a bitch to write your name in the snow in Arabic...

- Don't sweat the petty things, pet the sweaty things.

- Rice: 1.4 billion Chinese can't all be wrong.

- I'm dreaming of a better world where chickens can cross the road and
not have their motives questioned!

- If you can make a cheesecake you can install a Linux driver from source.

- Don't listen to the do-gooders, condoms are useless. They split, they
leak and they burst. And the human stomach can't handle the impact of
two kilos of cocaine.

- Users who XNA their posts are admitting that their ramblings aren't
worth reading.

- (on Windows) You know why "last known good configuration" almost
never works? Because the last known good configuration was a blank disk.
- Sinister Midget, 15 Jan 2009

*#* Signoff: labo-rat (find / -name \*yourbase\* -exec chown us:us {} \;)
 
R

Rainer Weikusat

On 14 Jan, 13:00, "David Webber" <[email protected]>
wrote:
I don't like having structures a different size from what I see on the
page.
It makes me nervous.
stop programming in C then.

Why?   [Actually I did, many years ago - I do it in C++ these days.]

because it's inherent in the language.

It [structure padding] is not 'inherent in the language'. It is a
requirement for certain architecture, possibly sensible on others, and
generally, an ABI documentation for a particular architecture or
architectures will formulate requirements in areas the C-standard
(which does not define an architecture) leaves open ("there may be
unnamed padding"). But unless I am very much mistaken, I already wrote
this yesterday.
A particular implementation *could* omit the padding but it's under
no obligation to do so.

If a particular implementation does not conform to the defined ABI for
a particular architecture, it is broken.

[...]

Because it will cause a 7 byte hole inside the structure for no
particular reason on a large number of architectures.
 
R

Rainer Weikusat

(e-mail address removed) writes:

[...]
do all linux machines have the same alignment and sizes?

This depends. But while the sizes differ, most are cuboids and these
align pretty well.
 
G

Guest

struct check_struct
{
double a;
char b;
char reserved[7];

If you do that you can see the padded bytes.
I don't think so. It will always show you the reserved member's

contents but I think the implementation is still free to insert
padding in any amount and at any location in this structure it
pleases, except at the beggining.<

I dare say, in principle, but I use compiler options which specify the
padding properties,

yuck. pragma pack being one of my pet hates.

and it would be unusual for 8 byte boundaries not to be
safe.

[I have large arrays of structures with many bit fields, and it is in my
interest, to arrange them so that padding is unnecessary,

ok. fair enough

and so I control
very carefully where the bit fields fit in relation to byte and word
boundaries. It's a useful principle of "defensive programming".]

that's a rather non-standard usage of the term "defensive
programming".
I tend to use it as a correctness term not a memory term
 
D

David Webber

Consider

struct A
{
char c;
double d;
char ca[7];
};

struct B
{
double d;
char ca[7];
char c;
};

A a[1000000];
B b[1000000];

with packing on 4 byte boundaries.

If there's any real need for packing on 4-byte boundaries, the
compiler should pad the struct to an exact multiple of 4 bytes, and
insert padding between c and d where needed, whether or not you insert
the declaration of 'ca'. If it doesn't, that's a QoI issue that should
lead you to look for a new compiler, not something you should work-
around by inserting useless fields.

My point in this case was that the memory required for the array is very
different in the two cases. And that it is much more than a
"quasi-legitimate reason for being concerned about the parts of a struct
that you don't use ". I would never write it as A.

More generally, whilst you can take these things on face value, let the
compiler do the packing, and decide not to care about it, you can do much
better by thinking about it. And packing explicitly with reserved fields is
one useful technique to aid the thinking. Using compiler options for
specifying the packing is another.

Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
 
D

David Webber

[I have large arrays of structures with many bit fields, and it is in my
interest, to arrange them so that padding is unnecessary, and so I
control very carefully where the bit fields fit in relation to byte and
word boundaries. It's a useful principle of "defensive programming".]

Your adding in a "reserved" field at the end is not controlling it.

Nor did I assert it would.
...
Of course, you are correct in suggesting that you should bare in mind
likely alignment restrictions when deciding on the order of fields and I
would agree with you that the following is BAD

struct bad {
double a;
char b;
double c;
}

Indeed, and that illustrates the utility of thinking hard about packing when
you design your structures. Using explicit reserved fields is one technique
which can help you, and that is all I meant in my reply to the OP.

Dave
--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
 
D

David Webber

yuck. pragma pack being one of my pet hates.

Well I have some pet hates too. But in the interests of practicality I
often have to live with them. My structures are complicated enough, and I
need to control their size enough, that specifying packing is too useful a
tool to get fussy about.
and it would be unusual for 8 byte boundaries not to be
safe.

[I have large arrays of structures with many bit fields, and it is in my
interest, to arrange them so that padding is unnecessary,

ok. fair enough

and so I control
very carefully where the bit fields fit in relation to byte and word
boundaries. It's a useful principle of "defensive programming".]

that's a rather non-standard usage of the term "defensive
programming".
I tend to use it as a correctness term not a memory term

All I mean by it is "writing code carefully to avoid problems down the
line".

Dave

--
David Webber
Author of 'Mozart the Music Processor'
http://www.mozart.co.uk
For discussion/support see
http://www.mozart.co.uk/mozartists/mailinglist.htm
 
J

Jan Kandziora

karthikbalaguru said:
I have the below structure.
struct check_struct{
double a;
char b;
};
My system reports the size of the above structure as 16 bytes.

I understand that there is some padding at the end of the above
structure and hence the size gets calculated to 16 bytes.
No. There could be padding *anywhere* inside the structure. If you have a
type of e.g. 7 bytes at the top, the next member could start at position 7,
8, 16 or any arbitrary value the compiler likes to have it.

But, how to view the data/info that are padded using a debugger
like gdb or visual c++ debugger ?
If you ever habe to deal with that (you shouldn't), you can always take the
difference of the pointer to the structured variable/constant itself and
the pointer to any element. But you shouldn't, as pointer arithmetics tend
to invoke any kind of errors as soon as the program is ported to another
platform.


If you really need to have the struct without any platform specific padding,
e.g. to send it over network to another machine, use the keyword "packed"
or the attribute "__packed__". The compiler will then insert *no padding at
all*, at the cost of some small performance loss when accessing the struct
members.

struct check_struct {
double a;
char b;
} __attribute__((__packed__));

See here: http://sig9.com/articles/gcc-packed-structures

Kind regards

Jan
 
J

James Kuyper

David said:
Consider

struct A
{
char c;
double d;
char ca[7];
};

struct B
{
double d;
char ca[7];
char c;
};

A a[1000000];
B b[1000000];

with packing on 4 byte boundaries.

If there's any real need for packing on 4-byte boundaries, the
compiler should pad the struct to an exact multiple of 4 bytes, and
insert padding between c and d where needed, whether or not you insert
the declaration of 'ca'. If it doesn't, that's a QoI issue that should
lead you to look for a new compiler, not something you should work-
around by inserting useless fields.

My point in this case was that the memory required for the array is very
different in the two cases. And that it is much more than a
"quasi-legitimate reason for being concerned about the parts of a struct
that you don't use ". I would never write it as A.

If saving memory is your objective, you'll save even more, when porting
such code to machines where 4-byte boundaries are not an issue, by
removing ca entirely. Doing so will almost certainly cause no problems
on machines where 4-byte boundaries are an issue, for the reasons given
above.
More generally, whilst you can take these things on face value, let the
compiler do the packing, and decide not to care about it, you can do
much better by thinking about it.

I do "think about it" insofar as we're talking about putting identical
types together, and larger types at the beginning of a struct, to
minimize the padding needed.

Worrying about the remote possibility that needed padding won't be
inserted by the compiler itself, and therefore deliberately inserting
your own padding, is a waste of time. That time is better spent
searching for a better compiler, or a fundamentally different algorithm
that might improve the performance of your code far more than any such
penny-ante details.
 
J

James Kuyper

Rainer said:
If a particular implementation does not conform to the defined ABI for
a particular architecture, it is broken.

True, but did he say anything to suggest that it didn't conform to the
relevant ABI?
 
J

Joe Pfeiffer

sasha said:
David said:
[snip]

Definitely not. The best approach is to make life easy for the
compiler and check that you are doing it optimally. It isn't hard
and you end up with much more efficient code.

Sorry, but LOL! Make it easy for the compiler? And here for the last
25 years I was, thinking compilers were to make it easy for people.

Compilers are tools like any other. A hammer is there to make life
easy for you, but your life is likely to be much more pleasant if you
don't use it to drive screws into sheet metal.

Similarly, how you code can have a large effect on how well the
compiler does its job.
 
L

lawrence.jones

Ben Pfaff said:
It would be quite unusual to insert padding before a member of
type char. Are there any implementations that do this?

I've heard tell of an implementation that aligned all members on at
least a word boundary for efficiency reasons.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top