Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Viewing the padded bytes

0 views
Skip to first unread message

karthikbalaguru

unread,
Jan 14, 2009, 3:41:46 AM1/14/09
to
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 ?

Thx in advans,
Karthik Balaguru

user923005

unread,
Jan 14, 2009, 4:11:15 AM1/14/09
to
On Jan 14, 12:41 am, karthikbalaguru <karthikbalagur...@gmail.com>
wrote:

typedef struct check_struct {
double a;
char b;
} check_struct_type;

check_struct_type cs = {0};
unsigned char *csp = (unsigned char *) &cs;

Why do you care? You cannot depend on anything about the padding
bytes.
They might contain all zeros on one invocation and 0xDEADBEE on
another.

Chris Ahlstrom

unread,
Jan 14, 2009, 6:58:43 AM1/14/09
to
After takin' a swig o' grog, user923005 belched out
this bit o' wisdom:

> They might contain all zeros on one invocation and 0xDEADBEE on
> another.

That's only 12 bits <grin>.

--
I never killed a man that didn't deserve it.
-- Mickey Cohen

David Webber

unread,
Jan 14, 2009, 8:00:45 AM1/14/09
to

"karthikbalaguru" <karthikb...@gmail.com> wrote in message
news:3f25b927-a9f1-4bce...@s9g2000prg.googlegroups.com...

I don't like having structures a different size from what I see on the page.
It makes me nervous. 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.

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

nick_keigh...@hotmail.com

unread,
Jan 14, 2009, 8:52:53 AM1/14/09
to
On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
wrote:
> "karthikbalaguru" <karthikbalagur...@gmail.com> wrote in message
> news:3f25b927-a9f1-4bce...@s9g2000prg.googlegroups.com...

> > 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 ?

why do you need to see the padding bytes?

> > I used watch windows but, it did not show the padded data .
> > Any ideas ?
>
> 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.


> 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?

swengi...@gmail.com

unread,
Jan 14, 2009, 9:43:28 AM1/14/09
to
On Jan 14, 8:00 am, "David Webber" <d...@musical-dot-demon-dot-co.uk>
wrote:
> "karthikbalaguru" <karthikbalagur...@gmail.com> wrote in message

>
> news:3f25b927-a9f1-4bce...@s9g2000prg.googlegroups.com...
>
> > 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 ?
>
> I don't like having structures a different size from what I see on the page.
> It makes me nervous.   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.

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.

Richard Tobin

unread,
Jan 14, 2009, 11:08:34 AM1/14/09
to
In article <e5fNnok...@TK2MSFTNGP06.phx.gbl>,
David Webber <da...@musical-dot-demon-dot-co.uk> wrote:

>I don't like having structures a different size from what I see on the page.
>It makes me nervous. So I would always write the above as
>
>struct check_struct
>{
> double a;
> char b;
> char reserved[7];
>};

Are you sure every compiler uses 7 bytes of padding?

-- Richard
--
Please remember to mention me / in tapes you leave behind.

Phil Da Lick!

unread,
Jan 14, 2009, 11:25:05 AM1/14/09
to
Richard Tobin wrote:
> In article <e5fNnok...@TK2MSFTNGP06.phx.gbl>,
> David Webber <da...@musical-dot-demon-dot-co.uk> wrote:
>
>> I don't like having structures a different size from what I see on the page.
>> It makes me nervous. So I would always write the above as
>>
>> struct check_struct
>> {
>> double a;
>> char b;
>> char reserved[7];
>> };
>
> Are you sure every compiler uses 7 bytes of padding?


Indeed. That's an assumption that shouldn't be made. You don't know what
kind of optimisations you might get. Best approach for struct padding is
to ignore it and let the compiler optimise as it sees fit.

David Schwartz

unread,
Jan 14, 2009, 2:27:09 PM1/14/09
to
On Jan 14, 12:41 am, karthikbalaguru <karthikbalagur...@gmail.com>
wrote:

> 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.

How do you know it's padding. Maybe a 'double' is 15 bytes on your
platform.

> 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 are programming in C, there is no reason you should have to know
or care.

Unless you are doing something very unusual, you are barking up the
wrong tree.

An example of a case where you could reasonably care would be one
where your memory allocator specifically sets assigned memory to a
particular value and freed memory to some other value. By seeing the
bytes that would presumably only be touched by the allocator, you can
tell if the structure was freed.

In any event, I've never heard of a debugger that doesn't let you view
any chunk of memory you want to view.

DS

user923005

unread,
Jan 14, 2009, 2:43:21 PM1/14/09
to
On Jan 14, 8:08 am, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:
> In article <e5fNnokdJHA....@TK2MSFTNGP06.phx.gbl>,

>
> David Webber <d...@musical-dot-demon-dot-co.uk> wrote:
> >I don't like having structures a different size from what I see on the page.
> >It makes me nervous.   So I would always write the above as
>
> >struct check_struct
> >{
> >    double a;
> >    char b;
> >    char reserved[7];
> >};
>
> Are you sure every compiler uses 7 bytes of padding?

One of mine uses 0, 2, 4, 8, or 16 bytes, depending on what I ask for.

David Webber

unread,
Jan 14, 2009, 7:46:23 PM1/14/09
to

<nick_keigh...@hotmail.com> wrote in message
news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...

On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
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.]


>> 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? 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. [And anyone who does program in C or C++ should be
close enough to what's going on underneath *never* to write that.]

David Webber

unread,
Jan 14, 2009, 8:00:01 PM1/14/09
to

"Phil Da Lick!" <phil_t...@spammerskissmyarse.hotmail.com> wrote in
message news:88adnaAxhP97jPPU...@posted.plusnet...

> Indeed. That's an assumption that shouldn't be made.

True.

>You don't know what kind of optimisations you might get. Best approach for
>struct padding is to ignore it and let the compiler optimise as it sees
>fit.

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.

David Webber

unread,
Jan 14, 2009, 7:52:03 PM1/14/09
to

<swengi...@gmail.com> wrote in message
news:44a909b5-7d25-4500...@k36g2000pri.googlegroups.com...

On Jan 14, 8:00 am, "David Webber" <d...@musical-dot-demon-dot-co.uk>
wrote:

> 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, 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, 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".]

David Webber

unread,
Jan 14, 2009, 8:11:17 PM1/14/09
to

"Richard Tobin" <ric...@cogsci.ed.ac.uk> wrote in message
news:gkl2m2$15ii$2...@pc-news.cogsci.ed.ac.uk...

> In article <e5fNnok...@TK2MSFTNGP06.phx.gbl>,
> David Webber <da...@musical-dot-demon-dot-co.uk> wrote:
>
>>I don't like having structures a different size from what I see on the
>>page.
>>It makes me nervous. So I would always write the above as
>>
>>struct check_struct
>>{
>> double a;
>> char b;
>> char reserved[7];
>>};
>
> Are you sure every compiler uses 7 bytes of padding?

When I said "always", it was an example. :-) The OP said he got 16
bytes, so his compiler is adding 7: I just made them explicit.

I use compiler options to specify such options, and usually set it to 4-byte
boundaries for 32 bit machines. [I don't know that *all* compilers allow
this, but
the ones I have tried all do IIRC.] With appropriate choices one could
probably get away
with:

struct check_struct
{
double a;
char b;

char reserved;
};

(with a 32 bit compiler).

David Webber

unread,
Jan 14, 2009, 8:02:24 PM1/14/09
to

"user923005" <dco...@connx.com> wrote in message
news:ea71b53c-08e2-4e0e...@t11g2000yqg.googlegroups.com...

On Jan 14, 8:08 am, rich...@cogsci.ed.ac.uk (Richard Tobin) wrote:

> One of mine uses 0, 2, 4, 8, or 16 bytes, depending on what I ask for.

Yes, but packing on single byte boundaries is probably not the most
efficient when compiling for a 32 bit machine. 4 byte boundaries is
probably a better choice.

David Webber

unread,
Jan 14, 2009, 7:57:05 PM1/14/09
to

"Richard Tobin" <ric...@cogsci.ed.ac.uk> wrote in message
news:gkl2m2$15ii$2...@pc-news.cogsci.ed.ac.uk...
> In article <e5fNnok...@TK2MSFTNGP06.phx.gbl>,
> David Webber <da...@musical-dot-demon-dot-co.uk> wrote:
>
>>I don't like having structures a different size from what I see on the
>>page.
>>It makes me nervous. So I would always write the above as
>>
>>struct check_struct
>>{
>> double a;
>> char b;
>> char reserved[7];
>>};
>
> Are you sure every compiler uses 7 bytes of padding?

When I said "always", it was an example. :-) I use compiler options to
specify such options. [I don't know that *all* compilers allow this, but
the ones I have tried all do IIRC.] So in some cases I'd probably get away
with:

struct check_struct
{
double a;
char b;

char reserved;
};

(with a 32 bit compiler).

Dave

cc

unread,
Jan 14, 2009, 8:31:12 PM1/14/09
to

Why don't you retards keep it in clc?

James Kuyper

unread,
Jan 15, 2009, 12:31:12 AM1/15/09
to
David Webber wrote:
>
> <nick_keigh...@hotmail.com> wrote in message
> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
> 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 all C structs can have a different size from what you "see on
the page". This applies even more so to C++; the requirements C++
imposes on POD structs are pretty much the same as for C structs. For
non-POD structs, C++ imposes even fewer restrictions on implementations
than it does for POD structs.

You'll therefore continue to be nervous for essentially the entire time
that you continue programming in either C or C++. Of course, some people
work better when they're nervous, in which case that won't be a
disadvantage.

Ian Collins

unread,
Jan 15, 2009, 12:47:31 AM1/15/09
to
David Webber wrote:
>
> <nick_keigh...@hotmail.com> wrote in message
> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
> 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.

--
Ian Collins

Golden California Girls

unread,
Jan 15, 2009, 2:07:35 AM1/15/09
to

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

Phil Da Lick!

unread,
Jan 15, 2009, 5:42:07 AM1/15/09
to
David Webber wrote:
>
> "Phil Da Lick!" <phil_t...@spammerskissmyarse.hotmail.com> wrote in
> message news:88adnaAxhP97jPPU...@posted.plusnet...
>
>> Indeed. That's an assumption that shouldn't be made.
>
> True.
>
>> You don't know what kind of optimisations you might get. Best approach
>> for struct padding is to ignore it and let the compiler optimise as it
>> sees fit.
>
> 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.


Not exactly sure what you mean here, but if you make assumptions about
generation x of compiler then your code *may* have issues for generation
x+1, x+2 etc.

Rainer Weikusat

unread,
Jan 15, 2009, 5:52:03 AM1/15/09
to
James Kuyper <james...@verizon.net> writes:
> David Webber wrote:
>> <nick_keigh...@hotmail.com> wrote in message
>> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
>> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
>> 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 all C structs can have a different size from what you "see on
> the page".

This is actually more subtle: The C-standard allows 'unnamed padding'
between any two members of a structure and at the end of it (6.2.7.1,
15 & 13), but doesn't contain anything regarding why an implementation
would insert such padding. Enter platform depenencies: Usually (this
is supposed to refer to anything remotely reasonable, ie NOT DOS),
output produced by different C compilers for a particular platform is
supposed to be binary-compatible, ie it is supposed to be possible to
link object files compiled with different compilers into a common
binary. Often, this is a requirement, because fundamental libraries,
like the C-library for UNIX(*), will have been compiled with some
'vendor compiler'. In order to achieve this, an ABI (application
binary interface) needs to be defined and documented and 'memory
layout of composite types' is one of the things described by it.
Assuming knowledge of the rules defined by the ABI, it is possible to
infer the memory layout of any C structure from its declaration.

Rainer Weikusat

unread,
Jan 15, 2009, 6:06:28 AM1/15/09
to
Ian Collins <ian-...@hotmail.com> writes:
> David Webber wrote:
>> <nick_keigh...@hotmail.com> wrote in message
>> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
>> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
>> 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?

The size of char is by definition 1. As 'by definition', double is a 8
byte 'double precisions floating point number'. This means that 'the
sizes' must not differ for a conforming C implementation. Usual
alignment requirements are either

- no requirement
- natural alignment, ie 8 byte quantities need to start
at addresses which are integral mutiples of 8

This could actually differ among different C implementations. But
people still don't run FTP servers on DSPs (or if they do, that's
entirely their problem), and for practical purposes, such machines
would first need to be identified and their alignment requirements
determined. If they were (for some reason) part of a set of
'interesting target architectures', conformance would be necessary.
Otherwise, that would just be a waste of both programmer and processor
time.

Måns Rullgård

unread,
Jan 15, 2009, 6:56:31 AM1/15/09
to
Rainer Weikusat <rwei...@mssgmbh.com> writes:

> Ian Collins <ian-...@hotmail.com> writes:
>> David Webber wrote:
>>> <nick_keigh...@hotmail.com> wrote in message
>>> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
>>> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
>>> 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?
>
> The size of char is by definition 1. As 'by definition', double is a 8
> byte 'double precisions floating point number'. This means that 'the
> sizes' must not differ for a conforming C implementation.

sizeof(char) == 1 by definition. CHAR_BIT doesn't have to be 8.
If sizeof(double)*CHAR_BIT == 64 and CHAR_BIT > 8, the above
struct will not be as expected.

In practise, CHAR_BIT is almost always 8, and POSIX/SUS even mandates
this.

--
Måns Rullgård
ma...@mansr.com

James Kuyper

unread,
Jan 15, 2009, 7:09:00 AM1/15/09
to
Rainer Weikusat wrote:
> Ian Collins <ian-...@hotmail.com> writes:
>> David Webber wrote:
>>> <nick_keigh...@hotmail.com> wrote in message
>>> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
>>> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
>>> 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?
>
> The size of char is by definition 1. ...

True.

> ... As 'by definition', double is a 8


> byte 'double precisions floating point number'.

This is not in fact defined, at least not by the C standard. Unless a
C99 implementation predefines the __STDC_IEC_559__ macro, the C
standard's requirements for double can in fact be met by a floating
point format substantially smaller than 64 bits, and such formats do
exist and are in use; I just recently had to write a program for
processing data which was stored in a 48-bit floating point format that,
if my calculations are correct, does in fact meet all of those requirements.

There are also systems where bytes are larger than octets, so even a
64-bit double can be stored in less than 8 bytes.

> ... This means that 'the


> sizes' must not differ for a conforming C implementation.

Incorrect.

> ... Usual


> alignment requirements are either
>
> - no requirement
> - natural alignment, ie 8 byte quantities need to start
> at addresses which are integral mutiples of 8
>
> This could actually differ among different C implementations. But
> people still don't run FTP servers on DSPs (or if they do, that's
> entirely their problem), and for practical purposes, such machines
> would first need to be identified and their alignment requirements
> determined. If they were (for some reason) part of a set of
> 'interesting target architectures', conformance would be necessary.
> Otherwise, that would just be a waste of both programmer and processor
> time.

I think what you're basically saying is that there's a particular range
of the systems that you consider important, and this works as you expect
it to on all of those systems. That's nice to know, but many people live
in a world where systems you dismiss as unimportant are very important
to them; and this code won't do what you expect it to do on many of
those systems.

Rainer Weikusat

unread,
Jan 15, 2009, 7:35:47 AM1/15/09
to

All kinds of things 'exist and are in use'. I arguably didn't read the
standard text careful enough and skipped over the exception clause.
But practially, this is again either obsolete or special purpose
hardware.

[...]

> There are also systems where bytes are larger than octets, so even a
> 64-bit double can be stored in less than 8 bytes.

... and these systems are either special purpose processors for
digitial signal processing or museum equipment.

[...]

>> ... Usual
>> alignment requirements are either
>> - no requirement
>> - natural alignment, ie 8 byte quantities need to start
>> at addresses which are integral mutiples of 8
>> This could actually differ among different C implementations. But
>> people still don't run FTP servers on DSPs (or if they do, that's
>> entirely their problem), and for practical purposes, such machines
>> would first need to be identified and their alignment requirements
>> determined. If they were (for some reason) part of a set of
>> 'interesting target architectures', conformance would be necessary.
>> Otherwise, that would just be a waste of both programmer and processor
>> time.
>
> I think what you're basically saying is that there's a particular
> range of the systems that you consider important, and this works as
> you expect it to on all of those systems.

And I "think" that this is not what I wrote. If YOU (please note that
this is not a statment about ME, cf the difference in spelling) write
C code which is supposed to be executed on, say, old mainframes with
9-bit bytes, this is a problem you will have to deal with (or anyone
else who happens to target such a platform for whatever
reasons). It is not a problem someone has to deal with or should deal
with who isn't targetting such platforms.

You are, of course, free to argue that software should generally be
written to the least common denominator of all computers which ever
existed or even all computer you could imagine to ever exist.

But I would really like to see a logical reason for that. As long as
you target me instead of the content of my text, a safe assumption is
that you haven't any.

David Webber

unread,
Jan 15, 2009, 7:49:19 AM1/15/09
to

"James Kuyper" <james...@verizon.net> wrote in message
news:ASzbl.344$eX3...@nwrddc01.gnilink.net...

>>>....


>>> stop programming in C then.
>>
>> Why? [Actually I did, many years ago - I do it in C++ these days.]
>
> Because all C structs can have a different size from what you "see on the
> page". This applies even more so to C++; the requirements C++ imposes on
> POD structs are pretty much the same as for C structs. For non-POD
> structs, C++ imposes even fewer restrictions on implementations than it
> does for POD structs.

Indeed, but my point is that with care you *can* get your data to have the
size you see on the page, that there is sometimes a good case for making
sure you do that, and...

> You'll therefore continue to be nervous for essentially the entire time
> that you continue programming in either C or C++. Of course, some people
> work better when they're nervous, in which case that won't be a
> disadvantage.

...and that this nervousness is indeed an advantage, not just because one
works better, but because it leads one to think about what the machine is
doing, rather than just taking code on face value. And C/C++ are languages
where taking code on face value without thinking about what the machine is
doing is rather dangerous.

In fact I'd say that anyone who programs C/C++ without my particular brand
of nervousness is heading for a fall :-)

David Webber

unread,
Jan 15, 2009, 7:55:12 AM1/15/09
to

"Ian Collins" <ian-...@hotmail.com> wrote in message
news:6t80viF...@mid.individual.net...

> What happens on a machine with different alignment and or sizes? What
> you have built is unnecessary non-portability.

I write software for Windows (and am viewing this cross-posted thread on
Microsoft's vc.language group). Portability?

But in fact the structures are perfectly portable to any compiler where you
can specify the n-byte packing alignment, which may not be a language
standard, but is surely not uncommon.

To be explicit: I would never dream of assuming that any given element is so
many bits after the start of the structure: that would be foolish. But
when you have arrays of thousands (or more) of them, control over the size
is bloody useful.

James Kuyper

unread,
Jan 15, 2009, 8:11:08 AM1/15/09
to
Rainer Weikusat wrote:
> James Kuyper <james...@verizon.net> writes:
>> Rainer Weikusat wrote:
...

>>> ... As 'by definition', double is a 8
>>> byte 'double precisions floating point number'.
>> This is not in fact defined, at least not by the C standard.
>> Unless a C99 implementation predefines the __STDC_IEC_559__ macro, the C
>> standard's requirements for double can in fact be met by a floating
>> point format substantially smaller than 64 bits, and such formats do
>> exist and are in use;
>
> All kinds of things 'exist and are in use'. I arguably didn't read the
> standard text careful enough and skipped over the exception clause.

The "exception clause" is the one that mandates IEEE-conforming double
precision format when predefining that macro - it's new in C99. It's the
general rule that allows for other formats.

> But practially, this is again either obsolete or special purpose
> hardware.

Most of the world's hardware can be dismissed as "special purpose", if
you're so inclined. Embedded processors, for instance, greatly exceed
desktop CPUs in their number and variety, even if you only consider the
multiple embedded processors that come with every desktop CPU. I can't
personally vouch for the accuracy of the claim that more new C code is
being written for them than for all desktop CPUs combined, but I
wouldn't be surprised to find that it's true.

My own personal experience with a non-IEEE 48 bit format that meets C's
requirements for double is MIL-STD-1750A, which I've mentioned in other
recent messages on comp.lang.c. It's nowhere near to being obsolete. In
1996 it was declared inactive for use in new military projects in the
USA; but the project I'm working on is non-military, and it's still in
active use here. According to Wikipedia,
<http://en.wikipedia.org/wiki/MIL-STD-1750A>, the Indian and Chinese
space programs also continue to use it.

James Kuyper

unread,
Jan 15, 2009, 8:30:17 AM1/15/09
to
David Webber wrote:
>
> "James Kuyper" <james...@verizon.net> wrote in message
> news:ASzbl.344$eX3...@nwrddc01.gnilink.net...
>
>>>> ....
>>>> stop programming in C then.
>>>
>>> Why? [Actually I did, many years ago - I do it in C++ these days.]
>>
>> Because all C structs can have a different size from what you "see on
>> the page". This applies even more so to C++; the requirements C++
>> imposes on POD structs are pretty much the same as for C structs. For
>> non-POD structs, C++ imposes even fewer restrictions on
>> implementations than it does for POD structs.
>
> Indeed, but my point is that with care you *can* get your data to have
> the size you see on the page, that there is sometimes a good case for
> making sure you do that, and...

You can do it only in an implementation-specific way. There's no general
way to do so. I'm not inclined to write unnecessarily
implementation-specific code. YMMV

>> You'll therefore continue to be nervous for essentially the entire
>> time that you continue programming in either C or C++. Of course, some
>> people work better when they're nervous, in which case that won't be a
>> disadvantage.
>
> ...and that this nervousness is indeed an advantage, not just because
> one works better, but because it leads one to think about what the
> machine is doing, rather than just taking code on face value. And
> C/C++ are languages where taking code on face value without thinking
> about what the machine is doing is rather dangerous.
>
> In fact I'd say that anyone who programs C/C++ without my particular
> brand of nervousness is heading for a fall :-)

The only quasi-legitimate reason I'm aware of for being concerned about
the parts of a struct that you don't use are if you plan to pass it
through a binary interface. If that's what's going on, then you should
be nervous, but for a very different reason; you shouldn't be using
structs for that purpose in the first place. You should be packing the
data into (or unpacking it from) an array (usually of type unsigned
char, unless all of the data is of a single data type).

Rainer Weikusat

unread,
Jan 15, 2009, 8:38:01 AM1/15/09
to
James Kuyper <james...@verizon.net> writes:

> Rainer Weikusat wrote:
>> James Kuyper <james...@verizon.net> writes:
>>> Rainer Weikusat wrote:
> ...
>>>> ... As 'by definition', double is a 8
>>>> byte 'double precisions floating point number'.
>>> This is not in fact defined, at least not by the C standard.
>>> Unless a C99 implementation predefines the __STDC_IEC_559__ macro, the C
>>> standard's requirements for double can in fact be met by a floating
>>> point format substantially smaller than 64 bits, and such formats do
>>> exist and are in use;
>>
>> All kinds of things 'exist and are in use'. I arguably didn't read
>> the standard text careful enough and skipped over the exception clause.
>
> The "exception clause" is the one that mandates IEEE-conforming double
> precision format when predefining that macro - it's new in C99. It's
> the general rule that allows for other formats.

The 'exception clause' in the text I was refering to is the one which
defines the exception, namely, that support for the 'type mappings'
described in F.2 (which I read) is optional, as stated in F.1.

That it is possible to defined 'exception clause' as something
different, especially, when refering to other parts of the C-standard
does not imply anything for my usage of this term.

>> But practially, this is again either obsolete or special purpose
>> hardware.
>
> Most of the world's hardware can be dismissed as "special purpose", if
> you're so inclined.

But I am not 'so inclined', as I already wrote, and insofar you are
'so inclined', as the sentence above suggest, please speak about you
instead of pretending to speak about me.

James Kuyper

unread,
Jan 15, 2009, 8:52:47 AM1/15/09
to
Rainer Weikusat wrote:
> James Kuyper <james...@verizon.net> writes:
>
>> Rainer Weikusat wrote:
>>> James Kuyper <james...@verizon.net> writes:
>>>> Rainer Weikusat wrote:
>> ...
>>>>> ... As 'by definition', double is a 8
>>>>> byte 'double precisions floating point number'.
>>>> This is not in fact defined, at least not by the C standard.
>>>> Unless a C99 implementation predefines the __STDC_IEC_559__ macro, the C
>>>> standard's requirements for double can in fact be met by a floating
>>>> point format substantially smaller than 64 bits, and such formats do
>>>> exist and are in use;
>>> All kinds of things 'exist and are in use'. I arguably didn't read
>>> the standard text careful enough and skipped over the exception clause.
>> The "exception clause" is the one that mandates IEEE-conforming double
>> precision format when predefining that macro - it's new in C99. It's
>> the general rule that allows for other formats.
>
> The 'exception clause' in the text I was refering to is the one which
> defines the exception, namely, that support for the 'type mappings'
> described in F.2 (which I read) is optional, as stated in F.1.

That's the same clause I'm referring to. It doesn't make support for
those type mappings optional. Those type mappings were already optional
before the __STDC_IEC_559__ macro was ever added to C99. What it
specifies is that systems have the option of predefining that macro, in
which case those mappings become mandatory.

>>> But practially, this is again either obsolete or special purpose
>>> hardware.
>> Most of the world's hardware can be dismissed as "special purpose", if
>> you're so inclined.
>
> But I am not 'so inclined', as I already wrote, and insofar you are
> 'so inclined', as the sentence above suggest, please speak about you
> instead of pretending to speak about me.

You're misreading the sentence if you think it suggests that I'm so
inclined. The dismissal of floating point formats as "obsolete or
special purpose hardware" was yours, not mine.

David Webber

unread,
Jan 15, 2009, 9:47:49 AM1/15/09
to

"Phil Da Lick!" <phil_t...@spammerskissmyarse.hotmail.com> wrote in
message news:GYmdnagzhb-fjvLU...@posted.plusnet...

> Not exactly sure what you mean here, but if you make assumptions about
> generation x of compiler then your code *may* have issues for generation
> x+1, x+2 etc.

I mean don't write:

struct X
{
unsigned a:1;
double b;
unsigned c:15;
};

write

struct X
{
double b;
unsigned c:15;
unsigned a:1;
};

If a new version of the compiler makes the second one worse in any way -
then my advice is to stick with the old one.

David Webber

unread,
Jan 15, 2009, 9:39:31 AM1/15/09
to

"James Kuyper" <james...@verizon.net> wrote in message
news:JTGbl.336$Dx....@nwrddc02.gnilink.net...

> The only quasi-legitimate reason I'm aware of for being concerned about
> the parts of a struct that you don't use are if you plan to pass it

> through a binary interface...

No. 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.

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

Phil Da Lick!

unread,
Jan 15, 2009, 9:56:42 AM1/15/09
to
David Webber wrote:
>
> "Phil Da Lick!" <phil_t...@spammerskissmyarse.hotmail.com> wrote in
> message news:GYmdnagzhb-fjvLU...@posted.plusnet...
>
>> Not exactly sure what you mean here, but if you make assumptions about
>> generation x of compiler then your code *may* have issues for
>> generation x+1, x+2 etc.
>
> I mean don't write:
>
> struct X
> {
> unsigned a:1;
> double b;
> unsigned c:15;
> };
>
> write
>
> struct X
> {
> double b;
> unsigned c:15;
> unsigned a:1;
> };
>
> If a new version of the compiler makes the second one worse in any way -
> then my advice is to stick with the old one.

Right. You're specifying the bit length. Well, not many programmers
bother with that but yes that would make a difference, but on a modern
computer not much of a difference unless you're allocating 10's or 100's
of thousands of these structs.

jameskuyper

unread,
Jan 15, 2009, 11:26:13 AM1/15/09
to
David Webber wrote:
> "James Kuyper" <james...@verizon.net> wrote in message
> news:JTGbl.336$Dx....@nwrddc02.gnilink.net...
>
> > The only quasi-legitimate reason I'm aware of for being concerned about
> > the parts of a struct that you don't use are if you plan to pass it
> > through a binary interface...
>
> No. 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.

Rainer Weikusat

unread,
Jan 15, 2009, 11:55:54 AM1/15/09
to
James Kuyper <james...@verizon.net> writes:
> Rainer Weikusat wrote:
>> James Kuyper <james...@verizon.net> writes:
>>> Rainer Weikusat wrote:
>>>> James Kuyper <james...@verizon.net> writes:
>>>>> Rainer Weikusat wrote:
>>> ...
>>>>>> ... As 'by definition', double is a 8
>>>>>> byte 'double precisions floating point number'.
>>>>> This is not in fact defined, at least not by the C standard.
>>>>> Unless a C99 implementation predefines the __STDC_IEC_559__ macro, the C
>>>>> standard's requirements for double can in fact be met by a floating
>>>>> point format substantially smaller than 64 bits, and such formats do
>>>>> exist and are in use;
>>>> All kinds of things 'exist and are in use'. I arguably didn't read
>>>> the standard text careful enough and skipped over the exception clause.
>>> The "exception clause" is the one that mandates IEEE-conforming double
>>> precision format when predefining that macro - it's new in C99. It's
>>> the general rule that allows for other formats.
>> The 'exception clause' in the text I was refering to is the one which
>> defines the exception, namely, that support for the 'type mappings'
>> described in F.2 (which I read) is optional, as stated in F.1.
>
> That's the same clause I'm referring to. It doesn't make support for
> those type mappings optional.

It does. F.2 states that

1 The C floating types match the IEC 60559 formats as follows:

-- The float type matches the IEC 60559 single format.

-- The double type matches the IEC 60559 double format.

and the annex itself is classified as 'normative'. Which means that a
conforming implementation has to behave accordingly, except that F.1
says that 'An implementation that defines __STDC_IEC_559__ shall
conform to the specifications in this annex.' Which defines an
exception relieving implementations from the unqualified requirement
in the following section.

Instead of presenting arguments supporting you (at least to me
somewhat unintelligible) thesis, you are still busy with 'fabrication
mock contradictions by suitable redefinition of terms used in the
orignal (that is in mine) text for a different purpose'. That's a
perfect way to "win" every "game" (change the rules such that you won
"by definition") and I congratulate you to your obvious political
talents. They are not helpful anyhow, though, insofar the intention is
to determine the meaning of some text (and they are probably not even
helpful in winning followers among a practically inclined audience,
because this type of 'talk for the purpose of talking' tends -
pardon my french - to piss people off who are simply not interested in
policy. Like me, for instance.

HAND.

jameskuyper

unread,
Jan 15, 2009, 12:42:02 PM1/15/09
to
Rainer Weikusat wrote:
...

> "by definition") and I congratulate you to your obvious political
> talents.

Believe me, I have none; otherwise people wouldn't get as upset with
me, the way you are, as often as they do.

There was really little point in my discussing whether or not that
clause was exceptional. It was just my way of expressing my surprise
about the fact that you were aware of an obscure new feature of C99,
which allows programmers to determine whether or not an implementation
supports IEEE/IEC 599, read the section which defines what it means to
provide such support, missed the fact that such support was optional
(which is stated in a moderately prominent location near the beginning
of that annex), and thereby reached the mistaken conclusion that it
was mandatory.

Simply reading the main portion of the standard, specifically sections
5.2.4.2.2 and 6.10.8p2, might have quickly led you to the suspicion,
at least, that IEEE double precision is not mandatory.

Ian Collins

unread,
Jan 15, 2009, 3:50:37 PM1/15/09
to
David Webber wrote:
>
> "Ian Collins" <ian-...@hotmail.com> wrote in message
> news:6t80viF...@mid.individual.net...
>
>> What happens on a machine with different alignment and or sizes? What
>> you have built is unnecessary non-portability.
>
> I write software for Windows (and am viewing this cross-posted thread on
> Microsoft's vc.language group). Portability?
>
That explains a lot.

> But in fact the structures are perfectly portable to any compiler where
> you can specify the n-byte packing alignment, which may not be a
> language standard, but is surely not uncommon.
>

They'd be just as portable without the unnecessary noise at the end.

> To be explicit: I would never dream of assuming that any given element
> is so many bits after the start of the structure: that would be
> foolish. But when you have arrays of thousands (or more) of them,
> control over the size is bloody useful.
>

Nothing you have added controls the size.

--
Ian Collins

sasha

unread,
Jan 15, 2009, 5:57:30 PM1/15/09
to David Webber
David Webber wrote:
>
[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.

Flash Gordon

unread,
Jan 15, 2009, 5:44:29 PM1/15/09
to
David Webber wrote:
>
> <swengi...@gmail.com> wrote in message
> news:44a909b5-7d25-4500...@k36g2000pri.googlegroups.com...
> On Jan 14, 8:00 am, "David Webber" <d...@musical-dot-demon-dot-co.uk>

> wrote:
>
>> 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, 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, 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. In
particular, it is highly unlikely to decrease the size but could well
increase it on some implementations (there could be speed benefits to
having an array start on a specific boundary on some implementations).
So for large arrays of structures (which you refer to in other posts) I
would say it was better in general to NOT have the reserved field.

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;
}

Chris M. Thomasson

unread,
Jan 15, 2009, 6:32:41 PM1/15/09
to
"karthikbalaguru" <karthikb...@gmail.com> wrote in message
news:3f25b927-a9f1-4bce...@s9g2000prg.googlegroups.com...
> 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;
}
___________________________________________________________

The Lost Packet

unread,
Jan 15, 2009, 6:33:42 PM1/15/09
to

fuck 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 {} \;)

nick_keigh...@hotmail.com

unread,
Jan 16, 2009, 3:23:07 AM1/16/09
to
On 15 Jan, 00:46, "David Webber" <d...@musical-dot-demon-dot-co.uk>
wrote:
> <nick_keighley_nos...@hotmail.com> wrote in message

> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
> 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. 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


> >> If you do that you can see the padded bytes.

> >what happens when they change?
>
> 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.

--
Nick Keighley


nick_keigh...@hotmail.com

unread,
Jan 16, 2009, 3:24:56 AM1/16/09
to
On 15 Jan, 07:07, Golden California Girls <gldncag...@aol.com.mil>
wrote:

> Ian Collins wrote:
> > David Webber wrote:
> >> <nick_keighley_nos...@hotmail.com> wrote in message

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?


The Lost Packet

unread,
Jan 16, 2009, 3:37:07 AM1/16/09
to

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...)

Rainer Weikusat

unread,
Jan 16, 2009, 3:41:46 AM1/16/09
to
nick_keigh...@hotmail.com writes:
> On 15 Jan, 00:46, "David Webber" <d...@musical-dot-demon-dot-co.uk>
> wrote:
>> <nick_keighley_nos...@hotmail.com> wrote in message
>> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
>> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
>> 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.

[...]

>>   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?

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

Rainer Weikusat

unread,
Jan 16, 2009, 3:44:35 AM1/16/09
to
nick_keigh...@hotmail.com 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.

nick_keigh...@hotmail.com

unread,
Jan 16, 2009, 3:55:55 AM1/16/09
to
On 15 Jan, 00:52, "David Webber" <d...@musical-dot-demon-dot-co.uk>
wrote:
> <swengineer...@gmail.com> wrote in message

> news:44a909b5-7d25-4500...@k36g2000pri.googlegroups.com...
> On Jan 14, 8:00 am, "David Webber" <d...@musical-dot-demon-dot-co.uk>
> wrote:
>
> > 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

--
Nick Keighley

"That's right!" shouted Vroomfondel "we demand rigidly defined
areas of doubt and uncertainty!"

David Webber

unread,
Jan 16, 2009, 4:29:06 AM1/16/09
to

"jameskuyper" <james...@verizon.net> wrote in message
news:c956d69e-7666-4551...@n33g2000pri.googlegroups.com...

>> 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.

David Webber

unread,
Jan 16, 2009, 4:57:56 AM1/16/09
to

<nick_keigh...@hotmail.com> wrote in message
news:0ff70a40-39a9-4a18...@u18g2000pro.googlegroups.com...

> 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".

David Webber

unread,
Jan 16, 2009, 4:52:29 AM1/16/09
to

"Flash Gordon" <sm...@spam.causeway.com> wrote in message
news:hrq446x...@news.flash-gordon.me.uk...

>> [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.

David Webber

unread,
Jan 16, 2009, 4:32:15 AM1/16/09
to

"Ian Collins" <ian-...@hotmail.com> wrote in message
news:6t9lstF...@mid.individual.net...

> Nothing you have added controls the size.

Indeed, but it helps me know about it. Other packing considerations do
allow you to control the size (like ordering data members of different
sizes).

David Webber

unread,
Jan 16, 2009, 5:22:42 AM1/16/09
to

"Phil Da Lick!" <phil_t...@spammerskissmyarse.hotmail.com> wrote in
message news:NtadnfjKLvgx0_LU...@posted.plusnet...

>> I mean don't write:
>>
>> struct X
>> {
>> unsigned a:1;
>> double b;
>> unsigned c:15;
>> };
>>
>> write
>>
>> struct X
>> {
>> double b;
>> unsigned c:15;
>> unsigned a:1;
>> };
>>
>> If a new version of the compiler makes the second one worse in any way -
>> then my advice is to stick with the old one.
>
> Right. You're specifying the bit length. Well, not many programmers bother
> with that but yes that would make a difference, but on a modern computer
> not much of a difference unless you're allocating 10's or 100's of
> thousands of these structs.

Ah but I can be. :-) [And yes, I might get away with things now which
would have broken the RAM when I originally wrote some of the code in the
late 1980s. But I don't think that's any reason to relax too much.]

I'll confess to much more heinous crimes now too. I can hear the shrieks
already. I save my structures with bit fields to disk by just copying so
many bytes of data. So a 1-bit field occupies 1 bit of disk when the file
is saved. As my software has evolved from version 1 to 9 my structures
have acquired more fields. If I can do this be eating into the "reserved"
fields (all of which are zeroed before saving to disk) and thus not change
the size of the structure, then new versions of the program can read files
saved by old ones, with essentially no (or at least minimal) change of code.
The alternative is saving bit fields as at least a byte each and multiplying
the memory image of my structures by 8 or more when saving to disk. I see
no reason to do that.

Also (even worse<g>) I have eight different structures stored in the same,
fairly large array. They therefore have to be the same size. Each has
different bit fields, with the (common) first three bits determining which
cast operator is used to interpret it. There would be lots of other
ways to do this, for example using doubly linked lists, inheritance, and
polymorphism, but at the expense of a significant loss of performance. I
am aware that purists will deprecate this, but being a purist butters no
parsnips :-(

And my version 1 (a 16bit Windows 3.1 program released in 1994) still works
on (32bit) Vista, and its files can still be read by version 9. It also
works fine, with no extra effort from me, under Windows emulators on the Mac
and Linux. So, whilst, in principle there are portability issues, it's a
long time since I worried about them.

Jan Kandziora

unread,
Jan 16, 2009, 6:37:41 AM1/16/09
to
karthikbalaguru schrieb:

>
> 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

James Kuyper

unread,
Jan 16, 2009, 6:40:04 AM1/16/09
to

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.

James Kuyper

unread,
Jan 16, 2009, 6:45:19 AM1/16/09
to
Rainer Weikusat wrote:
> nick_keigh...@hotmail.com writes:
>
> [...]
>
>> do all linux machines have the same alignment and sizes?
>
> This depends. ...

That's just another way of saying "No."

James Kuyper

unread,
Jan 16, 2009, 6:53:10 AM1/16/09
to
Rainer Weikusat wrote:
> nick_keigh...@hotmail.com writes:
>> On 15 Jan, 00:46, "David Webber" <d...@musical-dot-demon-dot-co.uk>
>> wrote:
>>> <nick_keighley_nos...@hotmail.com> wrote in message
>>> news:056d55b3-9e7b-46d7...@p2g2000prn.googlegroups.com...
>>> On 14 Jan, 13:00, "David Webber" <d...@musical-dot-demon-dot-co.uk>
>>> wrote:
...

>> 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.

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

Joe Pfeiffer

unread,
Jan 16, 2009, 10:20:33 AM1/16/09
to
sasha <a...@fox.net> writes:

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.

Phil Da Lick!

unread,
Jan 16, 2009, 10:59:02 AM1/16/09
to

Lol! Blasphemer! A guy who worked for me a decade or so ago used to do
that sort of thing.


jameskuyper

unread,
Jan 16, 2009, 2:22:34 PM1/16/09
to
David Webber wrote:
...

> I'll confess to much more heinous crimes now too. I can hear the shrieks
> already. I save my structures with bit fields to disk by just copying so
> many bytes of data. So a 1-bit field occupies 1 bit of disk when the file
> is saved.

That's fine, so long as no one needs to use your structs to write
programs for reading those files using a compiler that handles bit
fields differently from the way your compiler does. That would be
completely unacceptable for any program I have to write, but your
needs might be different.

> ... As my software has evolved from version 1 to 9 my structures


> have acquired more fields. If I can do this be eating into the "reserved"
> fields (all of which are zeroed before saving to disk) and thus not change
> the size of the structure, then new versions of the program can read files
> saved by old ones, with essentially no (or at least minimal) change of code.

This is a very good idea, with a long history, and is quite different
from worrying about padding bytes.

> The alternative is saving bit fields as at least a byte each and multiplying
> the memory image of my structures by 8 or more when saving to disk. I see
> no reason to do that.

That's not the only alternative. The more portable approach is to
store bit fields in arrays of unsigned char using bitwise operators.
It's a lot more work, so I understand why the use of less portable
approaches is tempting.

> Also (even worse<g>) I have eight different structures stored in the same,
> fairly large array.

That's what C unions are for.

> ... They therefore have to be the same size. Each has


> different bit fields, with the (common) first three bits determining which
> cast operator is used to interpret it. There would be lots of other
> ways to do this, for example using doubly linked lists, inheritance, and
> polymorphism,

I'm reading this message on comp.lang.c; C has no built-in support for
those last two techniques, though they can be emulated (poorly). If
you're using C++, it makes several guarantees that allow you to write
POD structs to disk, and read them back, just as you could in C. Use
of inheritance and polymorphism voids those guarantees; if your code
works despite that fact, you're relying heavily upon implementation-
specific behavior.

> And my version 1 (a 16bit Windows 3.1 program released in 1994) still works
> on (32bit) Vista, and its files can still be read by version 9. It also
> works fine, with no extra effort from me, under Windows emulators on the Mac
> and Linux. So, whilst, in principle there are portability issues, it's a
> long time since I worried about them.

Obviously.

Alec S.

unread,
Jan 16, 2009, 5:30:10 PM1/16/09
to
You know, in all the discussion that has been going on in this thread, I did not
see anyone give one of the most obvious reason for caring about padding: games
development. Any console dev will tell you that it’s important to consider data
alignment and padding when designing your data, especially since you have a
particilar platform with specific specs to code for. Not only do you have a set
amount of memory to work with, but you can perform several kinds of
optimizations if the data is structured right. You can reduce the number of
reads, stream data faster, process data more efficiently, and some hardware even
requires certain alignments for some things.

I think I’ve seen the #pragma pack directive before, but another way to get some
control over alignment is with __declspec(align(x)).

Last month (December 2008)’s issue of Game Developer Mag had an article on just
this thing. Noel has provided an interesting pair of functions called
aligned_malloc and aligned_free that you can use to allocate and free variables
according to a specified alignment by controling (and automating) the padding.


I guess there aren’t any game devs here. :|


--
Alec S.
news/alec->synetech/cjb/net


Ian Collins

unread,
Jan 16, 2009, 6:32:05 PM1/16/09
to
Alec S. wrote:
> You know, in all the discussion that has been going on in this thread, I did not
> see anyone give one of the most obvious reason for caring about padding: games
> development. Any console dev will tell you that it’s important to consider data
> alignment and padding when designing your data, especially since you have a
> particilar platform with specific specs to code for. Not only do you have a set
> amount of memory to work with, but you can perform several kinds of
> optimizations if the data is structured right. You can reduce the number of
> reads, stream data faster, process data more efficiently, and some hardware even
> requires certain alignments for some things.

That sounds like a general description of (particularly) embedded
development requirements!

> I think I’ve seen the #pragma pack directive before, but another way to get some
> control over alignment is with __declspec(align(x)).

On one of the cross posted platforms maybe, but not on others.

> I guess there aren’t any game devs here. :|

Nothing in the OP's postings relate to alignment performance, they only
relate to his limited ability to visualise structure padding.

--
Ian Collins

Alec S.

unread,
Jan 16, 2009, 7:21:01 PM1/16/09
to
Ian Collins wrote (in news:6tcjnlF...@mid.individual.net):

> > I guess there aren’t any game devs here. :|
>
> Nothing in the OP's postings relate to alignment performance, they only
> relate to his limited ability to visualise structure padding.

True, but the disccusions that followed covered all kinds of padding-related
issues, with most people saying there’s no reason to care about it. As a matter
of fact, the OP’s issue of seeing the padding is probably quite easy. A couple
of casts have been provided that can do it. I guess this thread is a great
example of both discussions going off-topic, and serendipitous collabortaion. :)

Nathan Mates

unread,
Jan 16, 2009, 8:13:29 PM1/16/09
to
In article <uvRfnsCe...@TK2MSFTNGP03.phx.gbl>,

Alec S. <nos...@127.0.0.1> wrote:
>I guess there aren't any game devs here. :|

I am a professional game developer, but haven't found it worthwhile
to chime in on this thread. We've had some discussions on this
internally, and this is what I've noted, internally, and in previous
discussions on microsoft.public.vc.*, that it's fairly easy to
minimize padding lossage by manually reordering structs. Consider this

struct S1
{
char m_C1;
double m_D1;
char m_C2;
double m_D2;
};

This is pretty much a worst-case, with 7 bytes of padding after
each char. But, if you sort your data members by size, largest, first,
you can reduce or eliminate padding. Put them in this order: (1)
16-byte aligned items (SSE or local platform equivalent). (2) 8-byte
items: doubles. (3) 8/4 byte items: pointers. These'll be 8-byte sized
once you go 64-bit. (4) 4-byte items: floats, ints. (5) 2-byte items:
shorts. (6) 1-byte items: chars. Thus, the above struct should look
like this:

struct S1
{
double m_D1;
double m_D2;
char m_C1;
char m_C2;
};

Conversely, you could turn array-of-structures into a structure
of arrays, such as:

S1 g_BigArray[1000];

And change that into, via either template fun or hand-unrolling,
into:

struct BigS1
{
double m_D1[1000];
double m_D2[1000];
char m_C1[1000];
char m_C2[1000];
};

BigS1 g_BigArray;

There's pretty much no packing issues w/ BigS1, versus
g_BigArray[1000]. But, this could hurt performance w/ cache locality
if you usually read d1/d2/c1/c2 for an item, then move on.

Unfortunately, C/C++ compilers are not allowed to dig into and
reorder your structs. After some years of development, or some
coworkers with an overactive sense of 'style' and grouping, a lot of
structs could be reduced in size. I'd love to have an (optional)
warning that'd say something like C###: struct has N bytes of padding,
but could be reordered to have only M padding bytes. Compilers are
treated as black boxes, but with a little bit of verbosity, useful
feedback can be generated.

Nathan Mates
--
<*> Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein

Alec S.

unread,
Jan 16, 2009, 10:27:20 PM1/16/09
to
Nathan Mates wrote (in news:u8ydnVEJuaMkrezU...@posted.visi):

> Unfortunately, C/C++ compilers are not allowed to dig into and
> reorder your structs. After some years of development, or some
> coworkers with an overactive sense of 'style' and grouping, a lot of
> structs could be reduced in size. I'd love to have an (optional)
> warning that'd say something like C###: struct has N bytes of padding,
> but could be reordered to have only M padding bytes. Compilers are
> treated as black boxes, but with a little bit of verbosity, useful
> feedback can be generated.

I like that idea, and it could probably be fairly easy to implement as well.

(I have yet to receive this month’s GDM, but I think Noel mentioned reordering
struct members in the article.)

David Webber

unread,
Jan 17, 2009, 6:33:44 AM1/17/09
to

"jameskuyper" <james...@verizon.net> wrote in message
news:ae85843c-ee27-493a...@k18g2000yqj.googlegroups.com...

> That's fine, so long as no one needs to use your structs to write
> programs for reading those files using a compiler that handles bit
> fields differently from the way your compiler does. That would be
> completely unacceptable for any program I have to write, but your
> needs might be different.

They're private.

>> The alternative is saving bit fields as at least a byte each and
>> multiplying
>> the memory image of my structures by 8 or more when saving to disk. I
>> see
>> no reason to do that.
>
> That's not the only alternative. The more portable approach is to
> store bit fields in arrays of unsigned char using bitwise operators.
> It's a lot more work, so I understand why the use of less portable
> approaches is tempting.

I thought about something similar to that, but came to the conclusion it was
overkill for my purposes.


>> Also (even worse<g>) I have eight different structures stored in the
>> same,
>> fairly large array.
>
> That's what C unions are for.

Yes. I looked into that when I first started writing the code in the late
1980s, but there were problems. I've forgotten what they were now, and
maybe they'd no longer be problems, or there'd be a way round. But I don't
want plain old data structures, but rather classes with lots of member
functions. In the end the simplest solution was home grown with three bits
indicating one of 8 interpretations of the data, each with its own
supporting class.

>> ... They therefore have to be the same size. Each has
>> different bit fields, with the (common) first three bits determining
>> which
>> cast operator is used to interpret it. There would be lots of other
>> ways to do this, for example using doubly linked lists, inheritance, and
>> polymorphism,
>
> I'm reading this message on comp.lang.c; C has no built-in support for
> those last two techniques, though they can be emulated (poorly).

Indeed.

> If
> you're using C++, it makes several guarantees that allow you to write
> POD structs to disk, and read them back, just as you could in C. Use
> of inheritance and polymorphism voids those guarantees; if your code
> works despite that fact, you're relying heavily upon implementation-
> specific behavior.

Yes. But in practice I write Windows code. Many years ago I used the
Borland C++ compiler; these days I use the Microsoft one. The code uses
vast swathes of the Windows API and I am unlikely to change compiler.
Most of my bit fields are grouped in sets which add up to 8 eg (3,3,2)
(2,3,2), (2,1,5) so that no bit field crosses a byte boundary. (Recently I
have relaxed that to word boundaries - with some caution.) So even if the
language lawyers tell me that padding is allowed between them, it would be
an implausible compiler which did that and I am prepared to take my chances
in the unlikely event that I switch compilers. :-)

[Of course the abomination that is Microsoft's "managed C++" - which doesn't
allow bit fields at all - is off limits to me.]

James Kuyper

unread,
Jan 17, 2009, 8:07:48 AM1/17/09
to
David Webber wrote:
>
> "jameskuyper" <james...@verizon.net> wrote in message
> news:ae85843c-ee27-493a...@k18g2000yqj.googlegroups.com...
...

>>> Also (even worse<g>) I have eight different structures stored in the
>>> same,
>>> fairly large array.
>>
>> That's what C unions are for.
>
> Yes. I looked into that when I first started writing the code in the
> late 1980s, but there were problems. I've forgotten what they were now,
> and maybe they'd no longer be problems, or there'd be a way round. But
> I don't want plain old data structures, but rather classes with lots of
> member functions.

I'm using a draft of the next version of the standard, n2723.pdf. A
promise that used to be attached to POD types in C++1998 now reads:

1.8p5: "... An object of trivial or standard-layout type (3.9)
shall occupy contiguous bytes of storage."

This is the key guarantee you need in order to write a struct to a file,
and read it back into a new uninitialized struct with defined behavior.
Well, you also need 3.9p4, but that's also tied to trivial types.

Therefore you don't need to use a POD struct to meet that requirement;
making it a trivial struct is sufficient. That doesn't rule out all
member functions. A trivial struct must have a trivial default ctor,
dtor, copy ctor, and copy assignment operator, and can't have any
virtual member functions. However, there's no other restrictions on the
possible member functions. Can you do what you want to do within the
restrictions on trivial structs (9p5)?

>> If
>> you're using C++, it makes several guarantees that allow you to write
>> POD structs to disk, and read them back, just as you could in C. Use
>> of inheritance and polymorphism voids those guarantees; if your code
>> works despite that fact, you're relying heavily upon implementation-
>> specific behavior.

That was a reference to 1.8p5 and 3.9p4, which are now tied to trivial
types rather than POD types, the way that they used to be. The
restrictions are pretty much the same with the new terminology. However,
I overstated my case: inheritance is allowed, so long as it's not virtual.

swengi...@gmail.com

unread,
Jan 17, 2009, 8:01:07 PM1/17/09
to
On Jan 14, 7:52 pm, "David Webber" <d...@musical-dot-demon-dot-co.uk>

wrote:
> <swengineer...@gmail.com> wrote in message
>
> news:44a909b5-7d25-4500...@k36g2000pri.googlegroups.com...
> On Jan 14, 8:00 am, "David Webber" <d...@musical-dot-demon-dot-co.uk>
> wrote:
>
> > 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, 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, 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".]
>
> Dave
> --
> David Webber
> Author of 'Mozart the Music Processor'http://www.mozart.co.uk
> For discussion/support seehttp://www.mozart.co.uk/mozartists/mailinglist.htm

I agree that you using this with specific compiler options means you
will probably not have a problem but the OP question was how to view
the padding with no information about what options he is or is not
using and this may or may not give him what he wants. I too have used
this approach often and with no problems but you need to understand
your compiler which I am not sure if this is the case or not for the
OP. Given he did not just view the memory to see what the contents of
the padding are I would guess he is fairly new to this.

nick_keigh...@hotmail.com

unread,
Jan 19, 2009, 4:37:17 AM1/19/09
to

I used the term "unless you're programming a toaster" as a shorthand
for any resource constrained embedded system. Eg. a toaster or
a games console.

I'm not disputing that you sometimes have to do tricks like this.
But you should use them when you need them. They should *not*
be your default coding style.

Even embedded code sometimes has to be surprisingly portable.
Those darn hardware engineers keep building new chips!


--
Nick Keighley

The beginning of wisdom for a [software engineer] is to recognize the
difference between getting a program to work, and getting it right.
-- M A Jackson, 1975

nick_keigh...@hotmail.com

unread,
Jan 19, 2009, 4:43:04 AM1/19/09
to
On 17 Jan, 03:27, "Alec S." <nos...@127.0.0.1> wrote:
> Nathan Mates wrote (innews:u8ydnVEJuaMkrezU...@posted.visi):

> >    Unfortunately, C/C++ compilers are not allowed to dig into and
> > reorder your structs. After some years of development, or some
> > coworkers with an overactive sense of 'style' and grouping, a lot of
> > structs could be reduced in size. I'd love to have an (optional)
> > warning that'd say something like C###: struct has N bytes of padding,
> > but could be reordered to have only M padding bytes. Compilers are
> > treated as black boxes, but with a little bit of verbosity, useful
> > feedback can be generated.
>
> I like that idea, and it could probably be fairly easy to implement as well.

I suspect you could implement it as a (nearly) standalone tool.
That is, I don't think you'd need a full syntax analysis of C.
But you would need some sort of code generation strategy configuration
to tell the tool how the compiler padded things.

<snip>

--
Nick Keighley


Rainer Weikusat

unread,
Jan 19, 2009, 5:05:44 AM1/19/09
to
nick_keigh...@hotmail.com writes:
> On 16 Jan, 22:30, "Alec S." <nos...@127.0.0.1> wrote:
>> You know, in all the discussion that has been going on in this thread, I did not
>> see anyone give one of the most obvious reason for caring about padding: games
>> development. Any console dev will tell you that it’s important to consider data
>> alignment and padding when designing your data, especially since you have a
>> particilar platform with specific specs to code for. Not only do you have a set
>> amount of memory to work with, but you can perform several kinds of
>> optimizations if the data is structured right. You can reduce the number of
>> reads, stream data faster, process data more efficiently, and some hardware even
>> requires certain alignments for some things.
>>
>> I think I’ve seen the #pragma pack directive before, but another way to get some
>> control over alignment is with __declspec(align(x)).
>>
>> Last month (December 2008)’s issue of Game Developer Mag had an article on just
>> this thing. Noel has provided an interesting pair of functions called
>> aligned_malloc and aligned_free that you can use to allocate and free variables
>> according to a specified alignment by controling (and automating) the padding.
>>
>> I guess there aren’t any game devs here. :|
>
> I used the term "unless you're programming a toaster" as a shorthand
> for any resource constrained embedded system. Eg. a toaster or
> a games console.

This doesn't make it any less nonsensical. Arranging struct members in
order to have them start at correctly aligned addresses without
compiler-inserted padding is a standard practice in kernel and network
programming. Actually, even formally specified binary communication
formats (supposed to be completely language-independent) often take
alignment issues into account. Aligning data to cacheline boundaries
is also a standard practice in code which needs to execute fastly. It
is even possible to do express this in a machine-independent way in
source code such that the compiled code will have the desired
properties.

[...]

> Even embedded code sometimes has to be surprisingly portable.
> Those darn hardware engineers keep building new chips!

Code which is written in the way I described above is often already
'surprisingly portable', eg Linux.

Ben Voigt [C++ MVP]

unread,
Jan 19, 2009, 12:11:16 PM1/19/09
to
> 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;
> }

Please explain what's bad about that (aside from the missing semicolon
following the type definition). Only in the unlikely circumstance that
sizeof (double) < sizeof (char).... and sizeof (char) is defined as 1 I'm
told. Any ordering of those three variables is likely to end up with sizeof
(bad) == 3 * sizeof (double) on architectures with alignment restrictions.

Interchange char and double and now you have an inefficient layout.

Lew Pitcher

unread,
Jan 19, 2009, 12:45:01 PM1/19/09
to
On January 19, 2009 12:11, in comp.os.linux.development.apps, Ben Voigt [C++
MVP] (r...@nospam.nospam) wrote:

With the given ordering, and an alignment requirement for the double
precision values, the compiler would have to insert padding after the char
element.

OTOH, with
struct alternative {
double a;
double c;
char b;
};
it is likely that no padding would be required after the char element.

Thus, the first ordering results in a structure that is larger than
necessary (as compared to the 2nd ordering).
--
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------


Keith Thompson

unread,
Jan 19, 2009, 1:11:50 PM1/19/09
to
[I'm temporarily not obeying the followup to comp.lang.c, since I'm
correcting an error that readers in the other newsgroup might be
interested in. I've redirected followups for this article to
comp.lang.c.]

Lew Pitcher <lpit...@teksavvy.com> writes:
[...]


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

[...]


> With the given ordering, and an alignment requirement for the double
> precision values, the compiler would have to insert padding after the char
> element.

Conceivably it could move b to the end of the word and insert padding
before it; that's permitted, but unlikely.

> OTOH, with
> struct alternative {
> double a;
> double c;
> char b;
> };
> it is likely that no padding would be required after the char element.
>
> Thus, the first ordering results in a structure that is larger than
> necessary (as compared to the 2nd ordering).

No, your "struct alternative" requires padding. The size of a
structure has to allow for arrays of that structure, and there are no
gaps between array elements. If you declare an array of two of these
structures:

struct alternative arr[2];

then arr[0].a, arr[0].b, arr[1].a, and arr[1].b must all be properly
aligned.

(This all assumes that double requires stricter alignment than char.)

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

sasha

unread,
Jan 19, 2009, 8:42:41 PM1/19/09
to
Joe Pfeiffer wrote:
[snip]

> 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.


I bet that thinking too much about such details today is
counter-productive. Whether I write a [i].something or a->something is
mostly irrelevant for the compiler - it will choose a better option
regardless.

What compiler cannot do is select a binary search instead of the bubble
search - time should be spent on such decisions, not what syntax to use
so the compiler will generate 'optimal' code.

.a

Rainer Weikusat

unread,
Jan 20, 2009, 7:45:10 AM1/20/09
to
sasha <a...@fox.net> writes:
> Joe Pfeiffer wrote:
> [snip]
>
>> 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.
>
> I bet that thinking too much about such details today is
> counter-productive.

Using languages compiled to machine code for tasks which do not
required this amount of attention to details is counterproductive
nowadays (and it has been this way for quite a while).

> Whether I write a [i].something or a->something is
> mostly irrelevant for the compiler - it will choose a better option
> regardless.

'The compiler' does not exist. A compiler I happened to work with
lately happened to have problems translating index loops, despite it
should theoretically be possible to even translate them to more
efficient code (and I know that another compiler for another
architecture would have done this). Consequently, I replaced the
indexed traversal with one using pointer arithemtic (after trying a
couple of other variants).

The morale of this story is that assumptions about compiler behaviour
are worthless: Either it doesn't really matter (but then the language
choice is most certainly "suboptimal") or the actual behaviour needs
to be determined and taken into account accordingly.

> What compiler cannot do is select a binary search instead of the
> bubble search - time should be spent on such decisions, not what
> syntax to use so the compiler will generate 'optimal' code.

To the best of my knowledge, there is no such thing as 'bubble
search' and I am really convinced that nobody should still spent any
time with something as well-researched as general sorting algorithms.
In most cases, there will be a library implementation of 'a sorting
algorithm' and that should be used where applicable. Otherwise, the
problem is usually sorting a linked list and the solution is
mergesort. But the question which general algorithm to use to
solve a particular problem and the question how this algorithm should
sensibly be implemented if it has to be implemented are actually
completely unrelated.

You are already (quite apparently) confused regarding the nature of
the problem: The difference between a[i].something and a->something is
not one of syntax, ie that they both 'look different', but one of
semantic: They name different operations. In particular,
a[i].something is defined in terms of two elementary operations, + and
->, as (a + i)->something (or (*(a + i)).something).

Kaz Kylheku

unread,
Jan 20, 2009, 2:17:41 PM1/20/09
to
On 2009-01-20, Rainer Weikusat <rwei...@mssgmbh.com> wrote:
> sasha <a...@fox.net> writes:
>> Joe Pfeiffer wrote:
>> [snip]
>>
>>> 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.
>>
>> I bet that thinking too much about such details today is
>> counter-productive.
>
> Using languages compiled to machine code for tasks which do not
> required this amount of attention to details is counterproductive
> nowadays (and it has been this way for quite a while).

This is an oversimplification of the issue. Compiling to machine code
is not aways a form of premature optimization. It's just an implementation
strategy.

Consider the language Common Lisp. There are some implementations of it
that use interpretive evaluation for interactive input (the REPL).

Then there are some that do not have an interpreter. Even expressions
evaluated at the listener prompt are translated to machine code and run.

The user experience of interacting with either one is identical.

Either compiling or interpreting code requires the /machine/ to
implement a lot of attention to detail, because the semantics of the
programming language is detailed.

What wastes the programmer's time is when he, not the machine, is asked to pay
attention to irrelevant details and responsibilities. That can happen in an
interpreted or compiled language. It's the fault of the language, not
its implementation strategy, though the two can be linked, because language
designs can be contrived in order to make particular implementation strategies
easy to achieve.

sasha

unread,
Jan 20, 2009, 6:25:08 PM1/20/09
to Rainer Weikusat
Rainer Weikusat wrote:
[snip]

> To the best of my knowledge, there is no such thing as 'bubble
> search' and I am really convinced that nobody should still spent any

You are correct - my typo - I was talking about sorting algorithms.
Shows when I used bubble sort last time <g>


>
> You are already (quite apparently) confused regarding the nature of
> the problem: The difference between a[i].something and a->something is

I don't think so. The problem is should a programmer be concerned with
some irrelevant coding detail? Even if a language police calls it
difference of semantics vs. syntax?

> not one of syntax, ie that they both 'look different', but one of
> semantic: They name different operations. In particular,
> a[i].something is defined in terms of two elementary operations, + and
> ->, as (a + i)->something (or (*(a + i)).something).

The beauty of a good optimizer is that both will produce the optimal
(and often identical) code.

jameskuyper

unread,
Jan 20, 2009, 7:01:21 PM1/20/09
to
sasha wrote:
> Whether I write a [i].something or a->something is
> mostly irrelevant for the compiler - it will choose a better option
> regardless.

Later, sasha wrote:
> Rainer Weikusat wrote:
...


> > You are already (quite apparently) confused regarding the nature of
> > the problem: The difference between a[i].something and a->something is
>
> I don't think so. The problem is should a programmer be concerned with
> some irrelevant coding detail? Even if a language police calls it
> difference of semantics vs. syntax?
>
> > not one of syntax, ie that they both 'look different', but one of
> > semantic: They name different operations. In particular,
> > a[i].something is defined in terms of two elementary operations, + and
> > ->, as (a + i)->something (or (*(a + i)).something).
>
> The beauty of a good optimizer is that both will produce the optimal
> (and often identical) code.

Producing identical code for a[i].something and (*(a+i)).something is
fully conforming, and quite normal. However, you were claiming that a
[i].something and a->something are equally good ways of writing the
same thing; a very different issue. Rainer was merely correctly
pointing out that those two expressions have very different semantics.
A compiler that generated identical code for both would be very
seriously non-conforming, unless it could be absolutely certain that
i==0.


sasha

unread,
Jan 20, 2009, 9:21:59 PM1/20/09
to
jameskuyper wrote:
[snip]


> Producing identical code for a[i].something and (*(a+i)).something is
> fully conforming, and quite normal. However, you were claiming that a

[snip]

> A compiler that generated identical code for both would be very
> seriously non-conforming, unless it could be absolutely certain that
> i==0.
>
>

Which one is it? Think of a function argument 'pointer to an array of
structures'.

.a

Rainer Weikusat

unread,
Jan 21, 2009, 7:22:19 AM1/21/09
to
sasha <a...@fox.net> writes:
> Rainer Weikusat wrote:

[...]

>> You are already (quite apparently) confused regarding the nature of
>> the problem: The difference between a[i].something and a->something

>> is not one of syntax, ie that they both 'look different', but one of
>> semantic:

[sentence restored]

> I don't think so.

Well, you were confusing the accidental (different 'look', ie syntax)
with the essential (different operation) ...

> The problem is should a programmer be concerned with
> some irrelevant coding detail? Even if a language police calls it
> difference of semantics vs. syntax?

... and your last sentence suggests that you still do. And the problem
is not 'should one be considered with the irrelevant', that's
suggestive question and the only reasonable answer is 'no', but what
precisely is 'irrelevant' and what isn't.

The particular difference in question is code-wise not irrelevant when
using gcc 4.0.3 and compiling for a pentium4 target. Depending on the
purpose of the affected code and the time which can be spent on tuning
it, the code difference may matter more or less, but that's a
different question and it doesn't have a simple, general answer.

>> not one of syntax, ie that they both 'look different', but one of
>> semantic: They name different operations. In particular,
>> a[i].something is defined in terms of two elementary operations, + and
>> ->, as (a + i)->something (or (*(a + i)).something).
>
> The beauty of a good optimizer is that both will produce the optimal
> (and often identical) code.

Except if 'optimal' is an attribute something created by 'the
optimizer' has by definition, which is true for the mathematical
meaning of 'optimization', but not for the bastardized use to express
'programmatic selection among a finite number of alternatives in order
to improve the numerical value of one or several quantifiable
attributes of the code which will be executed'. Just for the simple
reason that a general definition of when code should be considered
optimal isn't possible, eg "Is smaller better than faster?".

That said, since all of the expressions in my text above are defined
as being identical at the abstract machine operation level, a
compiler should certainly translate them to identical code. But not
because of 'a good optimizer', rather because expression subtree
constructed from will be identical.

James Kuyper

unread,
Jan 21, 2009, 7:34:26 AM1/21/09
to
sasha wrote:
> jameskuyper wrote:
> [snip]
>
>
>> Producing identical code for a[i].something and (*(a+i)).something is
>> fully conforming, and quite normal. However, you were claiming that a
>
> [snip]

Your snipping removed the following lines:

>> you were claiming that a

>> [i].something and a->something are equally good ways of writing the
>> same thing

Removal of those lines gives the false impression that the word "both"
in the following sentence refers to a[i].something and (*(a+i)).something.

>> A compiler that generated identical code for both would be very

In reality the word "both" in the above sentence refers to
a[i].something, and a->something.

>> seriously non-conforming, unless it could be absolutely certain that
>> i==0.
>>
>>
> Which one is it? Think of a function argument 'pointer to an array of
> structures'.
>
> .a

I have no idea what your question means. What does 'it' refer to? What
are the choices you're referring to when you ask "Which one"? What do
function arguments have to do with this?

I was indeed assuming, from context, that 'a' is a pointer to an array
of structures. a[i].something would therefore refer to the member named
'something' of the 'i+1'st member of that array. a->something refers to
the member named 'something' of the first element of that array; those
are two very different things, except in the special case where i==0.

This is a quite a trivial issue, one that doesn't deserve the number of
words that Rainer and I have spent pointing it out to you; but it still
seems to be the case that you don't understand what we were referring to.

Rainer Weikusat

unread,
Jan 21, 2009, 1:57:25 PM1/21/09
to
Kaz Kylheku <kkyl...@gmail.com> writes:
> On 2009-01-20, Rainer Weikusat <rwei...@mssgmbh.com> wrote:
>> sasha <a...@fox.net> writes:
>>> Joe Pfeiffer wrote:
>>> [snip]
>>>
>>>> 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.
>>>
>>> I bet that thinking too much about such details today is
>>> counter-productive.
>>
>> Using languages compiled to machine code for tasks which do not
>> required this amount of attention to details is counterproductive
>> nowadays (and it has been this way for quite a while).
>
> This is an oversimplification of the issue. Compiling to machine code
> is not aways a form of premature optimization. It's just an implementation
> strategy.
>
> Consider the language Common Lisp.

[...]

My use of terms was arguably imprecise and Lisp is a good example to
demonstrate that. Assuming that some Lisp implementation actually has
a compiler which can create native code[*], there are two general ways
of using it:

- run the compiler on the Lisp-program which has not been
specially annotated with information only relevant for such
a compiler: The result will be a compiled program which has
the Lisp runtime linked to it, but uses the same
general-purpose subroutines the uncompiled program would
use, too.

- annotate the (already working) Lisp-code with
compiler-relevant information, especially, with
(preferably restrictive) type-declarations: the compiler can
then either open-code certain operations (like addition) in
the same way a C-compiler usually would or at least use less
general subroutines which will execute more efficiently.

My use of 'language compiled to machine code' would be analogous to
the second way of using such a Lisp-compiler: Include lots of
meta-information about the data structures used by the program in the
code in order to achieve more efficient runtime behaviour at the
expense of an increase in development and debugging time (and likely,
also an increase in 'bugginess' of the final result). It's just that
'people' think 'C++' if they see 'language compiled to machine code' and
'f***ing mess of nested brackets' when they see 'Common Lisp' (this
is, of course, again an oversimplification).

[*] One could argue that the existence of such compilers is a
historical accident dating back to the time when computers
where generally a lot slower and less ressourceful than
nowadays. Eg, there used to be 'a Perl compiler' which was
(very) roughly equivalent to 'Lisp compilers', but it was
recently dropped from the language distribution, because it
never attracted enough interest to even make it work reliably,
vulgo: the execution speed of the interpreted bytecode was
demonstrably 'good enough'.

[...]

> What wastes the programmer's time is when he, not the machine, is
> asked to pay attention to irrelevant details and responsibilities.
> That can happen in an interpreted or compiled language. It's the
> fault of the language, not its implementation strategy,

In my opinion, its the fault of the person who chose a particular
implementation language when this choice results in time wasted on
details that wouldn't really have mattered for achieving a usable
solution to some problem.

sasha

unread,
Jan 21, 2009, 3:08:05 PM1/21/09
to
James Kuyper wrote:
[snip]

> I was indeed assuming, from context, that 'a' is a pointer to an array
> of structures. a[i].something would therefore refer to the member named
> 'something' of the 'i+1'st member of that array. a->something refers to
> the member named 'something' of the first element of that array; those
> are two very different things, except in the special case where i==0.
>
> This is a quite a trivial issue, one that doesn't deserve the number of
> words that Rainer and I have spent pointing it out to you; but it still
> seems to be the case that you don't understand what we were referring to.

It's always a great honor when someone of your stature speaks down to
me. I do appreciate it.

In case you still have interest, consider this:

void func( some_struct const * a ) {

...
for ( int i = 0; i < size; ++i ) {
do_func( a [i].member );
}

for ( int i; i < size; ++i, ++a ) {
do_func( a->member );
}
}

Hate to point this out to such a all-knowing person, but the pointer 'a'
may be incremented and it doesn't necessarily have to point to the first
element of an array.

I would be surprised if a decent optimizer doesn't generate identical
code for both loops.

Good day.

jameskuyper

unread,
Jan 21, 2009, 4:06:18 PM1/21/09
to
sasha wrote:
...

> It's always a great honor when someone of your stature speaks down to
> me. I do appreciate it.

Don't mention it; the honor was well deserved.

> In case you still have interest, consider this:
>
> void func( some_struct const * a ) {
>
> ...
> for ( int i = 0; i < size; ++i ) {
> do_func( a [i].member );
> }
>
> for ( int i; i < size; ++i, ++a ) {
> do_func( a->member );
> }
> }

You said "Whether I write a[i].something or a->something is mostly
irrelevant for the compiler, - it will choose a better option
regardless." I tried this on your example, but my compiler failed to
"choose a better option" (whatever that means):

void func( some_struct const * a ) {

...
for ( int i = 0; i < size; ++i ) {

do_func( a->member );
}

for ( int i; i < size; ++i, ++a ) {

do_func( a[i].member );
}
}

I conclude that "Whether I write a [i].something or a->something" is
in fact, very relevant for the compiler.

Whether you use array indices or pointers is irrelevant, as long as
you use them correctly, but that's not what you chose to say.

Rainer Weikusat

unread,
Jan 22, 2009, 3:53:52 AM1/22/09
to
sasha <a...@fox.net> writes:

[...]

> void func( some_struct const * a ) {
>
> ...
> for ( int i = 0; i < size; ++i ) {
> do_func( a [i].member );
> }
>
> for ( int i; i < size; ++i, ++a ) {
> do_func( a->member );
> }
> }

[...]

> I would be surprised if a decent optimizer doesn't generate identical
> code for both loops.

IOW, an 'optimizer' would only be considered 'decent' by you if it
does. As I have already written at least twice: To my great surprise,
I have recently encountered a gcc version which didn't. Not for this
particular useless for-loop, but a more complicated real one, which I
orignally coded as indexed traversal and then recoded using pointer
arithmetic because the loop happened to warrant enough attention.

The bottom line is still that speculating about such issues, which
includes any attempt at contrived demonstrations, is a useless
exercise.

sasha

unread,
Jan 22, 2009, 1:41:03 PM1/22/09
to
Rainer Weikusat wrote:

> IOW, an 'optimizer' would only be considered 'decent' by you if it
> does. As I have already written at least twice: To my great surprise,

Certainly, there are enough non-decent optimizers <g>

> I have recently encountered a gcc version which didn't. Not for this

And you happened to use one.


>
> The bottom line is still that speculating about such issues, which
> includes any attempt at contrived demonstrations, is a useless
> exercise.

I agree that speculating is often useless (if not destructive - see the
current economic situation <g>).

That's why 'speculating' too much up-front and agonizing over a
particular approach (i.e. indexed vs pointer) is a waste of time. Once
it's shown the code has problems at run-time, then it's time to think
about more efficient options.


Regards,
.a

Rainer Weikusat

unread,
Jan 22, 2009, 2:38:00 PM1/22/09
to
sasha <a...@fox.net> writes:
> Rainer Weikusat wrote:
>> IOW, an 'optimizer' would only be considered 'decent' by you if it
>> does. As I have already written at least twice: To my great surprise,
>
> Certainly, there are enough non-decent optimizers <g>
>
>> I have recently encountered a gcc version which didn't. Not for this
>
> And you happened to use one.

More correctly: I happen to know that at least one compiler exists
which does not act in accordance with your beliefs about
compilers, which is sufficient to demonstrate that they are wrong.

Bo Persson

unread,
Jan 22, 2009, 2:46:01 PM1/22/09
to

I also met a few compilers in the mid 1980s that were easy to beat, on
the then current hardware.

That doesn't mean that anyone can easily write well scheduled assembly
code for today's multi-issue, multi-level-cache hardware.

Should we add multi-chip and multi-core requirements as well? :-)


Bo Persson


sasha

unread,
Jan 22, 2009, 5:39:09 PM1/22/09
to
Rainer Weikusat wrote:

> More correctly: I happen to know that at least one compiler exists
> which does not act in accordance with your beliefs about
> compilers, which is sufficient to demonstrate that they are wrong.

The fact you know of one compiler (for embedded HW, probably) doesn't
mean I have to spend time thinking about that it may produce sub-optimal
code.

Nowhere in what I wrote you will find a statement that all compilers
have good optimizers. What you will find is an objection that one should
be spending time 'making it easy' for the compilers.

.a

0 new messages