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

padding?

2 views
Skip to first unread message

Zach

unread,
Jun 13, 2009, 4:07:32 AM6/13/09
to
I looked in the index of K&R and couldn't find anything on padding.
Could someone please explain what padding is in C programming and
illustrate it with some code. I heard it is often used in constructing
network packets.

Zach

Richard Heathfield

unread,
Jun 13, 2009, 4:34:53 AM6/13/09
to
Zach said:

Padding is simply a region of data storage that it is convenient to
"waste". Precisely whom is convenienced depends on the situation.

The following example demonstrates that the reason for padding is
not always obvious to people even when explained ad nauseam.

Once upon a time, I attempted to convince a US airline to insert
some padding into a cross-pond data structure. That's because
(structurally) the relevant bit looked something like this:

T1 d1;
T2 d2;
T3 d3;
T1 d4;
T2 d5;
T1 d6;
T2 d7;
T3 d8;
T1 d9;
T2 d10;

(except there were more fields in each group, and more groups). I
recognised straight away that inserting sizeof(T3) bytes of padding
between d5 and d6 and after d10 (and, in the original, in a couple
of other places too) would allow me to treat that whole set of data
as an array of smaller structs within the outer struct. This would
simplify the code I was writing for processing that structure.

The US airline refused to make such a pointless stupid change, so I
solved my problem another way, using an array of pointers. A little
while later, however, /their/ programmers noticed the same thing,
and a change notification duly arrived, notifying us of a change to
the structure which was, essentially, the precise change I'd
proposed. (I looked at my pointer array code, saw that it would
still work just fine, and decided to leave it as is.)

Whenever you use bitfields in a structure that don't occupy a whole
number of bytes, you effectively introduce padding into the
structure. (Sometimes this can happen even if your bitfields /do/
occupy a whole number of bytes.)

The tm_yday field in a struct tm is essentially padding as far as
many people are concerned (but those who /do/ use it would
disagree!).

Padding in network packets: there's a byte of padding at the end of
the TCP header, purely so that the data is four-byte-aligned. For
some machines, this is an advantage (although the cynical part of
me suspects it was put there purely to make the diagram look
neater). The TCP protocol insists that this padding is set to 0.

Note also that six /other/ bits of the header are unused, but
reserved for future use. ("Reserved for future use" very often
means the same as "padding"!)

Compilers can use padding, too, and often do. They are, for example,
allowed to insert padding into data structures (normally for
alignment purposes) after /any/ member they like (but not at the
very beginning of the structure, before the first member).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Forged article? See
http://www.cpax.org.uk/prg/usenet/comp.lang.c/msgauth.php
"Usenet is a strange place" - dmr 29 July 1999

Tor Rustad

unread,
Jun 13, 2009, 7:35:24 AM6/13/09
to

Yes, networkork headers often have padding bits or bytes. Check the
specs on the ethernet, IP and TCP headers.

Padding is unused bits or bytes, in a protocol you might only need e.g.
30 bits, then it's convenient to add 2 padding bits so that an
implementation can read/write the fields as 32-bit units.

Another point is that padding may be used for future extensions of the
protocol, without breaking backward compability. Hence, if unused
padding bits/bytes are put into usage by supporting a new specification
at one side, the old software at another side may still continue to work.

In C, padding is often used by compilers between struct members, for
example:

struct s
{
char c;
<- compiler might insert 7 padding bytes here
double d;
};

this because the target CPU might have alignment requirements on double
access, or that double access is faster when e.g. aligned to e.g. 8
byte boundery.

Hence in C, you can <no> assume that

struct s mys;

memcpy(&mys, ...);

will work, due to potential padding bytes. To load some data into a
struct, you need to do that struct member for for struct member, unless
using a non-standard pragma for struct packing.


--
Tor <echo bwz...@wvtqvm.vw | tr i-za-h a-z>

Squeamizh

unread,
Jun 13, 2009, 5:15:32 PM6/13/09
to
On Jun 13, 1:34 am, Richard Heathfield <r...@see.sig.invalid> wrote:
> Zach said:
>
> > I looked in the index of K&R and couldn't find anything on
> > padding. Could someone please explain what padding is in C
> > programming and illustrate it with some code. I heard it is often
> > used in constructing network packets.
>
> Padding is simply a region of data storage that it is convenient to
> "waste". Precisely whom is convenienced depends on the situation.

[...]

> The tm_yday field in a struct tm is essentially padding as far as
> many people are concerned (but those who /do/ use it would
> disagree!).

Then I would strongly suggest that it isn't padding. Correct me if
I'm wrong; you seem to be saying that padding is any data that you
don't find useful in a particular situation.

Richard Heathfield

unread,
Jun 13, 2009, 6:02:20 PM6/13/09
to
Squeamizh said:

> On Jun 13, 1:34 am, Richard Heathfield <r...@see.sig.invalid>
> wrote:

<snip>


>
>> The tm_yday field in a struct tm is essentially padding as far as
>> many people are concerned (but those who /do/ use it would
>> disagree!).
>
> Then I would strongly suggest that it isn't padding. Correct me
> if I'm wrong; you seem to be saying that padding is any data that
> you don't find useful in a particular situation.

...but that /someone/ or /something/ finds useful, and thus we can't
just leave the padding out. Yes. That's not a formal definition,
obviously, but it seems to me to be a very pragmatic way of looking
at padding.

Spiros Bousbouras

unread,
Jun 13, 2009, 6:07:14 PM6/13/09
to
On 13 June, 12:35, Tor Rustad <bwz...@wvtqvm.vw> wrote:
>
> In C, padding is often used by compilers between struct members, for
> example:
>
> struct s
> {
> char c;
> <- compiler might insert 7 padding bytes here
> double d;
>
> };
>
> this because the target CPU might have alignment requirements on double
> access, or that double access is faster when e.g. aligned to e.g. 8
> byte boundery.
>
> Hence in C, you can <no> assume that
>
> struct s mys;
>
> memcpy(&mys, ...);
>
> will work, due to potential padding bytes. To load some data into a
> struct, you need to do that struct member for for struct member, unless
> using a non-standard pragma for struct packing.

What won't work ? It's not clear what you have in mind for "...".

If structures s1 and s2 are of the same type then you can do s1=s2
or memmove(&s1 , &s2 , sizeof(s2)) Both will "load some data"
to s1 without explicitly assigning to each member.

--
Ever real life has plot holes.

Ian Collins

unread,
Jun 13, 2009, 6:19:24 PM6/13/09
to
Tor Rustad wrote:
>
> Hence in C, you can <no> assume that
>
> struct s mys;
>
> memcpy(&mys, ...);
>
> will work, due to potential padding bytes. To load some data into a
> struct, you need to do that struct member for for struct member, unless
> using a non-standard pragma for struct packing.

Or use a static initialiser, or even just a plain old copy.

--
Ian Collins

Tor Rustad

unread,
Jun 13, 2009, 7:02:03 PM6/13/09
to
Spiros Bousbouras wrote:
> On 13 June, 12:35, Tor Rustad <bwz...@wvtqvm.vw> wrote:
>> In C, padding is often used by compilers between struct members, for
>> example:
>>
>> struct s
>> {
>> char c;
>> <- compiler might insert 7 padding bytes here
>> double d;
>>
>> };
>>
>> this because the target CPU might have alignment requirements on double
>> access, or that double access is faster when e.g. aligned to e.g. 8
>> byte boundery.
>>
>> Hence in C, you can <no> assume that
>>
>> struct s mys;
>>
>> memcpy(&mys, ...);
>>
>> will work, due to potential padding bytes. To load some data into a
>> struct, you need to do that struct member for for struct member, unless
>> using a non-standard pragma for struct packing.
>
> What won't work ? It's not clear what you have in mind for "...".

I had a buffer in mind, which is the typical case when a network packet
arrives or you read some data from disk.

> If structures s1 and s2 are of the same type then you can do s1=s2
> or memmove(&s1 , &s2 , sizeof(s2)) Both will "load some data"
> to s1 without explicitly assigning to each member.

Yes

Tor Rustad

unread,
Jun 13, 2009, 7:33:37 PM6/13/09
to

Well yes, initializer will work, but a copy require the source object to
have the same padding, as the struct layout your compiler has chosen for
the destination object.

That is generally not the case.

Such layout may even change on the same compiler, depending on the
compiler settings, let say if optimizing for speed instead of space.

The important point for OP is, sending raw structs over the wire, or
storing raw structs to the disk, is a bad idea due to padding.

Bjarni Juliusson

unread,
Jun 13, 2009, 7:47:55 PM6/13/09
to
Tor Rustad wrote:
>> What won't work ? It's not clear what you have in mind for "...".
>
> I had a buffer in mind, which is the typical case when a network packet
> arrives or you read some data from disk.

Put another way, if you have a buffer

char buf[1024];

which has some received network packet in it, you can't do

struct packet_header *header=(struct packet_header *)buf;

and start reading the members of header and expect everything to be
fine. The packet has all members aligned according to the network
protocol, probably with very little padding, and the compiler probably
aligns for instance ints and chars differently, inserting padding in
between them or even reordering them inside the struct. There are no
guarantees (well almost no guarantees, go read the standard).

So, as an example, say you have a network protocol with a header that
contains an 8 bit packet type and a 16 bit payload length. It probably
looks like this:

offset 0: type [byte]
offset 1: length [high byte] [low byte]

Now if you declare a struct for that as

struct header{
char type;
short length;
};

on a little-endian 32 bit computer with no native 16 bit data type and a
32 bit alignment restriction, you'll probably get a struct that looks
like this in memory:

offset 0: type [byte]
offset 1: [padding] [padding] [padding]
offset 4: length [low byte] [2:nd byte]
[3:rd byte] [high byte]

If you set a pointer like that to the beginning of the buffer and try to
read the members, you'll get the right packet type, but the length will
be outside of the header data and might segfault your program, or it
might point to the second byte of the payload, or it might point to
something else entirely.

Without the padding, the length member of the struct would start at the
right place but would still read four bytes instead if the two defined
in the protocol and present in the buffer, and on top of that they would
be in the wrong order.

So that was a quick lesson in padding and network byte order.


Bjarni
--

INFORMATION WANTS TO BE FREE

Spiros Bousbouras

unread,
Jun 13, 2009, 8:22:53 PM6/13/09
to
On 14 June, 00:47, Bjarni Juliusson <bja...@update.uu.se> wrote:
> The packet has all members aligned according to the network
> protocol, probably with very little padding, and the compiler probably
> aligns for instance ints and chars differently, inserting padding in
> between them or even reordering them inside the struct.

A compiler cannot reorder the fields of a structure. Paragraph 5 of
6.5.8 says:

When two pointers are compared, the result depends on the
relative locations in the address space of the objects
pointed to.
[...]
If the objects pointed to are members of the same aggregate
object, pointers to structure members declared later compare
greater than pointers to members declared earlier in the
structure,

--
If kids realised how annoying they can be they would have a lot more
appreciation for their parents.

Bjarni Juliusson

unread,
Jun 13, 2009, 10:00:08 PM6/13/09
to
Spiros Bousbouras wrote:
> On 14 June, 00:47, Bjarni Juliusson <bja...@update.uu.se> wrote:
>> The packet has all members aligned according to the network
>> protocol, probably with very little padding, and the compiler probably
>> aligns for instance ints and chars differently, inserting padding in
>> between them or even reordering them inside the struct.
>
> A compiler cannot reorder the fields of a structure. Paragraph 5 of
> 6.5.8 says:
>
> When two pointers are compared, the result depends on the
> relative locations in the address space of the objects
> pointed to.
> [...]
> If the objects pointed to are members of the same aggregate
> object, pointers to structure members declared later compare
> greater than pointers to members declared earlier in the
> structure,

You are right, I apologise. In fact, it is stated more clearly in
paragraph 13 of 6.7.2.1:

Within a structure object, the [...] members [...] have
addresses that increase in the order in which they are declared.

I misremembered, and thought the only guarantee was that the first
element always ended up first in memory.

Can anyone tell me what the rationale is? It seems to me like it might
be sensible to, say, take all the char members in a struct and pack them
together at the end to preserve alignment of any int members without
lots of padding.

Stephen Sprunk

unread,
Jun 13, 2009, 10:50:01 PM6/13/09
to
Bjarni Juliusson wrote:
> You are right, I apologise. In fact, it is stated more clearly in
> paragraph 13 of 6.7.2.1:
>
> Within a structure object, the [...] members [...] have
> addresses that increase in the order in which they are declared.
>
> I misremembered, and thought the only guarantee was that the first
> element always ended up first in memory.
>
> Can anyone tell me what the rationale is? It seems to me like it might
> be sensible to, say, take all the char members in a struct and pack them
> together at the end to preserve alignment of any int members without
> lots of padding.

It flows partially from the requirement that any initial member types
common to two structs be laid out in the same order and at the same
offsets, which is used widely for crude polymorphism. The compiler
can't know when compiling unit A what other structs will be in unit B
(which may not even be written yet) and how many, if any, of their
initial members may be in common. Therefore, the only reordering of
members that _could_ potentially be allowed is fitting later members
into the padding between earlier elements.

Once you're going to put the above restriction on reordering, you don't
lose much if you ban reordering entirely and therefore comply with the
Rule of Least Surprise -- the programmer put the members in a particular
order, so it would be logical for him to expect them to be laid out that
way in memory. If he cares about the padding (which is, in most cases,
a micro-optimization and therefore Evil(tm)), he can reorder them
himself to minimize it.

More importantly, though, I suspect that all known compilers at the time
followed this rule already, so it was probably a matter of C89
formalizing the behavior to keep future implementations from doing
something that wouldn't be compatible. Remember, ANSI's primary goal
was to standardize existing practice, not to create an ideal language.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Isaac Jaffe

Rainer Weikusat

unread,
Jun 14, 2009, 10:47:18 AM6/14/09
to
Richard Heathfield <r...@see.sig.invalid> writes:
> Squeamizh said:
>
>> On Jun 13, 1:34 am, Richard Heathfield <r...@see.sig.invalid>
>> wrote:
> <snip>
>>
>>> The tm_yday field in a struct tm is essentially padding as far as
>>> many people are concerned (but those who /do/ use it would
>>> disagree!).
>>
>> Then I would strongly suggest that it isn't padding. Correct me
>> if I'm wrong; you seem to be saying that padding is any data that
>> you don't find useful in a particular situation.
>
> ...but that /someone/ or /something/ finds useful, and thus we can't
> just leave the padding out. Yes. That's not a formal definition,
> obviously, but it seems to me to be a very pragmatic way of looking
> at padding.

It is nevertheless wrong: 'Padding' is additional storage beyond the
one necessary to hold, say, the data values of a C struct, which is
used to achieve some effect beyond what is specified in the
C-standard, typically, to conform to ABI-requirements regarding
alignment of objects of a particular size (for instance, '4-byte
integers must always be stored at addresses evenly divisble by four')
in order to be able to generate more efficient machine code (for
instance, because properly aligned 4-byte values can be manipulated
with machine instructions operating on 'words' of data). This is
something different than 'data members someone may consider to be
useless' (and hence, 'a waste of space').

Richard Heathfield

unread,
Jun 14, 2009, 11:40:25 AM6/14/09
to
Rainer Weikusat said:

> Richard Heathfield <r...@see.sig.invalid> writes:
>> Squeamizh said:
>>
>>> On Jun 13, 1:34 am, Richard Heathfield <r...@see.sig.invalid>
>>> wrote:
>> <snip>
>>>
>>>> The tm_yday field in a struct tm is essentially padding as far
>>>> as many people are concerned (but those who /do/ use it would
>>>> disagree!).
>>>
>>> Then I would strongly suggest that it isn't padding. Correct me
>>> if I'm wrong; you seem to be saying that padding is any data
>>> that you don't find useful in a particular situation.
>>
>> ...but that /someone/ or /something/ finds useful, and thus we
>> can't just leave the padding out. Yes. That's not a formal
>> definition, obviously, but it seems to me to be a very pragmatic
>> way of looking at padding.
>
> It is nevertheless wrong: 'Padding' is additional storage beyond
> the one necessary

Precisely.

> to hold, say, the data values of a C struct,
> which is used to achieve some effect beyond what is specified in
> the C-standard,

Not necessarily. If I define a struct like this:

struct S1
{


T1 d1; T2 d2; T3 d3;

T1 d4; T2 d5; T3 Padding;


T1 d6; T2 d7; T3 d8;

};

then, given appropriate definitions of T1, T2, and T3, we have
padding that is fully specified by the C Standard.

> typically, to conform to ABI-requirements
> regarding alignment of objects of a particular size (for instance,
> '4-byte integers must always be stored at addresses evenly
> divisble by four') in order to be able to generate more efficient
> machine code (for instance, because properly aligned 4-byte values
> can be manipulated with machine instructions operating on 'words'
> of data). This is something different than 'data members someone
> may consider to be useless' (and hence, 'a waste of space').

I think we're in violent agreement. At least, I think I think we
are. That is, I know what you mean and I agree with it, but I'm not
entirely sure whether you know what I mean.

Giorgos Keramidas

unread,
Jun 14, 2009, 8:30:41 PM6/14/09
to
On Sun, 14 Jun 2009 04:00:08 +0200, Bjarni Juliusson <bja...@update.uu.se> wrote:
> You are right, I apologise. In fact, it is stated more clearly in
> paragraph 13 of 6.7.2.1:
>
> Within a structure object, the [...] members [...] have
> addresses that increase in the order in which they are declared.
>
> I misremembered, and thought the only guarantee was that the first
> element always ended up first in memory.
>
> Can anyone tell me what the rationale is? It seems to me like it might
> be sensible to, say, take all the char members in a struct and pack
> them together at the end to preserve alignment of any int members
> without lots of padding.

For a struct with no aggregate members, this may not be quite as useful
(but then I may also be missing an important detail behind the rule).
But it seems quite sensible for code that includes structs inside other
structs, i.e.:

struct methods;

struct object {
long magic;
size_t size;
long type;
struct methods *fptr;
size_t nfptr;
};

struct myobject {
struct object parent;
char mydata[10];
};

This is commonly used to 'tag' structures of different types. If the
compiler was allowed to reorder the fields of `myobject', it would be
quite unpredictable where myobject.parent would end up.

Boon

unread,
Jun 15, 2009, 7:46:22 AM6/15/09
to
Richard Heathfield wrote:

> Padding in network packets: there's a byte of padding at the end of
> the TCP header, purely so that the data is four-byte-aligned. For
> some machines, this is an advantage (although the cynical part of
> me suspects it was put there purely to make the diagram look
> neater). The TCP protocol insists that this padding is set to 0.

You lost me.

http://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure

Assuming no options (i.e. header size = 20 octets), the last two fields of a TCP
header are Checksum and Urgent pointer.

"Urgent pointer (16 bits) � if the URG flag is set, then this 16-bit field is an
offset from the sequence number indicating the last urgent data byte"

Perhaps you were thinking of headers with options?
(In that case, padding might be needed.)

> Note also that six /other/ bits of the header are unused, but
> reserved for future use. ("Reserved for future use" very often
> means the same as "padding"!)

Only 4 bits are reserved for future use and should be set to zero.
CWR and ECE were defined in 2001.

http://tools.ietf.org/html/rfc3168

Regards.

karthikbalaguru

unread,
Jun 15, 2009, 9:39:20 AM6/15/09
to

Padding is used for Boundary Alignment w.r.t processor.
It is very important to take care of boundary
alignment while designing database's in C language in embedded
environment as it improves the performance and also in saving
the memory. So, Database Design is very important.

Karthik Balaguru

Richard Heathfield

unread,
Jun 15, 2009, 1:35:01 PM6/15/09
to
Boon said:

> Richard Heathfield wrote:
>
>> Padding in network packets: there's a byte of padding at the end
>> of the TCP header, purely so that the data is four-byte-aligned.
>> For some machines, this is an advantage (although the cynical
>> part of me suspects it was put there purely to make the diagram
>> look neater). The TCP protocol insists that this padding is set
>> to 0.
>
> You lost me.
>

> <wiki URL>

I wrote my article after referring to:

<http://www.faqs.org/rfcs/rfc793.html>

<snip>

> http://tools.ietf.org/html/rfc3168

Then it's possible that I'm out of date. (In fact, it's quite
probable.)

Tor Rustad

unread,
Jun 16, 2009, 7:19:28 AM6/16/09
to
Bjarni Juliusson wrote:

> You are right, I apologise. In fact, it is stated more clearly in
> paragraph 13 of 6.7.2.1:
>
> Within a structure object, the [...] members [...] have
> addresses that increase in the order in which they are declared.

Yes, this specify the direction of the ordering that has to be used in
the storage layout of structure members. The requirement for sequential
ordering of structure members is here

6.2.5p20

A structure type describes a sequentially allocated nonempty set of
member objects


> I misremembered, and thought the only guarantee was that the first
> element always ended up first in memory.
>
> Can anyone tell me what the rationale is?

The offsetof() macro was an invention of the Standard committe, so one
rationale was to avoid breaking code that predated the standard.

> It seems to me like it might be sensible to, say, take all the
> char members in a struct and pack them
> together at the end to preserve alignment of any int members without
> lots of padding.

If it matters, we can achive that in C by ordering the struct members
manually according to a qualified guess on alignment requirements [1]

struct pack
{
double d;
long l;
short s;
char c;
};

thus avoiding "lots of padding". I believe most implementations of other
languages would use the storage layout as required in C, but exceptions
do exist, for example there should be implementations of Ada that use
re-ordering of record fields as an optimization. Such reorder could
depend on Ada's

pragma Pack(...)
pragma Optimize(...)

where the former minimise padding, while the latter optimize for speed.
There is one quite interesting optimization trick conforming C compilers
can't use for tree algoritms, let say we have

struct node
{
struct data data;
struct node *next;
};

then improved speed could result, if the storage layout internally was

struct data data[N];
struct node *(next[N]);

Due to improved locallity of data above, improved chance of cache hit is
expected.

[1] While C compilers don't have to document the alignment requirements,
some implementations support the non-standard __alignof__(),

Richard Bos

unread,
Jun 23, 2009, 3:03:06 PM6/23/09
to
Rainer Weikusat <rwei...@mssgmbh.com> wrote:

> Richard Heathfield <r...@see.sig.invalid> writes:

> > ...but that /someone/ or /something/ finds useful, and thus we can't
> > just leave the padding out. Yes. That's not a formal definition,
> > obviously, but it seems to me to be a very pragmatic way of looking
> > at padding.
>
> It is nevertheless wrong: 'Padding' is additional storage beyond the
> one necessary to hold, say, the data values of a C struct, which is
> used to achieve some effect beyond what is specified in the
> C-standard, typically, to conform to ABI-requirements regarding
> alignment of objects of a particular size (for instance, '4-byte
> integers must always be stored at addresses evenly divisble by four')
> in order to be able to generate more efficient machine code (for
> instance, because properly aligned 4-byte values can be manipulated
> with machine instructions operating on 'words' of data). This is
> something different than 'data members someone may consider to be
> useless' (and hence, 'a waste of space').

What's more, padding is never a data member at all. The defining
characteristic of padding is that it exists because of the space it
takes, not because of the value it may or may even never have. Any data
member, even a data member only few people find useful, should at some
point in its life have a value that those people want to refer to.
Padding may change randomly or never at all, and you can blot over it
without affecting anyone.

Richard

Eric Sosman

unread,
Jun 23, 2009, 3:50:17 PM6/23/09
to
Richard Bos wrote:
>
> What's more, padding is never a data member at all. The defining
> characteristic of padding is that it exists because of the space it
> takes, not because of the value it may or may even never have. Any data
> member, even a data member only few people find useful, should at some
> point in its life have a value that those people want to refer to.
> Padding may change randomly or never at all, and you can blot over it
> without affecting anyone.

So I guess you'd say "unused; must be zero" bits are
not padding?

--
Eric Sosman
eso...@ieee-dot-org.invalid

Tim Rentsch

unread,
Jun 23, 2009, 5:21:54 PM6/23/09
to
ral...@xs4all.nl (Richard Bos) writes:

In

struct s {
unsigned foo : 4;
unsigned : 12;
unsigned bas : 16;
};

would you say the data member between foo and bas is there as
padding? If we have

struct s x, y;
memset( &y, 0, sizeof y );
x = y;

is the unnamed bit-field member guaranteed to hold zeroes, or
not? If it is not guaranteed to hold zeroes (because structure
assignments are not required to copy padding bits) does that mean
it's illegal to put an unnamed bit-field member at the start of a
structure (because structures are not allowed to have padding at
the beginning)? Or is this a case of a data member that exists
just because of the space it takes, yet is not padding? But if
the values of unnamed bit-fields are supposed to be useful (ie,
and not padding), why are they indeterminate even after
initialization? (6.7.8 p 9)

Mark McIntyre

unread,
Jun 23, 2009, 5:50:54 PM6/23/09
to

I believe the original context was with respect to structs, not unused
bits in a bitfield object.

--
Mark McIntyre

CLC FAQ <http://c-faq.com/>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

Eric Sosman

unread,
Jun 23, 2009, 6:20:49 PM6/23/09
to
Mark McIntyre wrote:
> Eric Sosman wrote:
>> Richard Bos wrote:
>>>
>>> What's more, padding is never a data member at all. The defining
>>> characteristic of padding is that it exists because of the space it
>>> takes, not because of the value it may or may even never have. Any data
>>> member, even a data member only few people find useful, should at some
>>> point in its life have a value that those people want to refer to.
>>> Padding may change randomly or never at all, and you can blot over it
>>> without affecting anyone.
>>
>> So I guess you'd say "unused; must be zero" bits are
>> not padding?
>
> I believe the original context was with respect to structs, not unused
> bits in a bitfield object.

The original question mentioned padding in connection
with "constructing network packets." True, it was only
in an "I heard ..." context, but a structs-only view of
the discussion seems a bit restrictive.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Richard Bos

unread,
Jun 24, 2009, 4:27:13 AM6/24/09
to
Tim Rentsch <t...@alumnus.caltech.edu> wrote:

> ral...@xs4all.nl (Richard Bos) writes:
>
> > What's more, padding is never a data member at all. The defining
> > characteristic of padding is that it exists because of the space it
> > takes, not because of the value it may or may even never have. Any data
> > member, even a data member only few people find useful, should at some
> > point in its life have a value that those people want to refer to.
> > Padding may change randomly or never at all, and you can blot over it
> > without affecting anyone.
>
> In
>
> struct s {
> unsigned foo : 4;
> unsigned : 12;
> unsigned bas : 16;
> };
>
> would you say the data member between foo and bas is there as
> padding?

Since you can't access its value at all (stupid tricks with unsigned
char pointers aside), and that value is therefore irrelevant, yes.

> If we have
>
> struct s x, y;
> memset( &y, 0, sizeof y );
> x = y;
>
> is the unnamed bit-field member guaranteed to hold zeroes, or
> not?

In y, yes, but they're irrelevant; in x, they're not even guaranteed to
be zero.

> (because structures are not allowed to have padding at the beginning)?

Structures are not allowed to have _implementation-inserted_ padding
_bytes_ at the beginning. You, as the user-programmer, are allowed to
add as much padding of your own as pleases you. There is nothing in the
Standard to stop you from declaring

struct t {
unsigned char padding[37];
long int single_data_member;
unsigned char more_padding[51];
}

Do not be surprised to find extra padding added after _your_ member
called padding, and before or after more_padding.

Tell me, did you _really_ not know all this, or are you being an awkward
arsehole just to make the point that you _can_ be an awkward arsehole?

Richard

Richard Bos

unread,
Jun 24, 2009, 4:27:12 AM6/24/09
to
Eric Sosman <eso...@ieee-dot-org.invalid> wrote:

That depends on whether that is a political or a technical "must". If
there is reasonable expectation that it may in the future be used, and
can then get other values, it's not. If it's only required to be zero
out of a show of future planning, it's padding. I admit that this may,
for an outsider, be difficult to judge.

Richard

James Kanze

unread,
Jun 24, 2009, 4:35:13 AM6/24/09
to
On Jun 15, 7:35 pm, Richard Heathfield <r...@see.sig.invalid> wrote:
> Boon said:

> > Richard Heathfield wrote:

> >> Padding in network packets: there's a byte of padding at
> >> the end of the TCP header, purely so that the data is
> >> four-byte-aligned. For some machines, this is an advantage
> >> (although the cynical part of me suspects it was put there
> >> purely to make the diagram look neater). The TCP protocol
> >> insists that this padding is set to 0.

> > You lost me.

> > <wiki URL>

> I wrote my article after referring to:

> <http://www.faqs.org/rfcs/rfc793.html>

The diagram in this RFC does show three bytes of options and one
of padding at the end. The text, however, makes it clear that
the header may end immediately after the urgent pointer field,
that the size of the options field is variable, that the ammount
of padding is also variable---the sum of the sizes of the
options and the padding must be a multiple of 4.

> <snip>

> >http://tools.ietf.org/html/rfc3168

> Then it's possible that I'm out of date. (In fact, it's quite
> probable.)

RFC 793 is still the basic definition of TCP, although there are
later RFC's which update it (e.g. by specifying additional
options or additional control bits).

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

unread,
Jun 24, 2009, 4:45:15 AM6/24/09
to
On Jun 14, 1:47 am, Bjarni Juliusson <bja...@update.uu.se> wrote:
> Tor Rustad wrote:
> >> What won't work ? It's not clear what you have in mind for
> >> "...".

> > I had a buffer in mind, which is the typical case when a
> > network packet arrives or you read some data from disk.

> Put another way, if you have a buffer

> char buf[1024];

> which has some received network packet in it, you can't do

> struct packet_header *header=(struct packet_header *)buf;

> and start reading the members of header and expect everything
> to be fine. The packet has all members aligned according to
> the network protocol, probably with very little padding, and
> the compiler probably aligns for instance ints and chars
> differently, inserting padding in between them or even
> reordering them inside the struct.

And the network may use a different representation for negative
values, or even a different byte size. The RFC's specify
octets, the C standard bytes. Octets are eight bits, bytes may
be any number of bits, depending on the hardware (although I've
never heard of less than six, the C standard requires at least
eight, and Posix does require exactly eight). Posix also
requires 2's complement, so on a Posix compliant system, the
only difference in representation can be byte order.

En general, anytime you're moving between network data and
internal data, you need some sort of marshalling code.

Ben Bacarisse

unread,
Jun 24, 2009, 7:04:27 AM6/24/09
to
ral...@xs4all.nl (Richard Bos) writes:

What on Earth is the point of being rude? Tim seems to be someone who
relishes detail. If you want to avoid such detailed arguments, then
simply don't reply. If you do, then you will find there is almost
always some valid point being made.

In this case, I suspect he was moved to post by the first remark he
quoted:

>> > What's more, padding is never a data member at all.

since his example was of a data member which both of you agree is
padding. From what follows that quote, it is clear that you did not
mean it as written. You were saying something along the lines of
"padding is never a proper data member at all" or better yet you could
have joined the two sentences to show you were extending this remark
with "the defining characteristic of padding...".

It is both the a major strength and tragic weakness of Usenet that
these sorts of discussions are what it does best.

--
Ben.

Keith Thompson

unread,
Jun 24, 2009, 2:18:42 PM6/24/09
to

There are at least three distinct meanings of "padding".

The C standard defines "padding bits" for integer types, and "padding
bytes" for structs. (It doesn't define padding for floating-point or
pointer types, because it doesn't specify enough about either for the
concept to be meaningful -- though I suppose it could do so for FP.)

What we're talking about here is what "padding" means in a non-C
context. I know of no rigorous definition (say, one that excludes
foam rubber), and no way to resolve any disagreements about whether an
unused byte in an IP packet qualifies as "padding".

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

Tim Rentsch

unread,
Jun 25, 2009, 1:20:41 PM6/25/09
to
ral...@xs4all.nl (Richard Bos) writes:

> Tim Rentsch <t...@alumnus.caltech.edu> wrote:
>
> > ral...@xs4all.nl (Richard Bos) writes:
> >
> > > What's more, padding is never a data member at all. The defining
> > > characteristic of padding is that it exists because of the space it
> > > takes, not because of the value it may or may even never have. Any data
> > > member, even a data member only few people find useful, should at some
> > > point in its life have a value that those people want to refer to.
> > > Padding may change randomly or never at all, and you can blot over it
> > > without affecting anyone.
> >
> > In
> >
> > struct s {
> > unsigned foo : 4;
> > unsigned : 12;
> > unsigned bas : 16;
> > };
> >
> > would you say the data member between foo and bas is there as
> > padding?
>
> Since you can't access its value at all (stupid tricks with unsigned
> char pointers aside), and that value is therefore irrelevant, yes.

C trivia question: Is it possible to access the value of an unnamed
bit-field in a way that's portable and not implementation dependent?

Answer: of course there are implementation dependent ways (besides
using unsigned chars, there are other kinds of type punning, or
reading/writing a binary file), but it may surprise some people to
know that there is also a portable way to do so:

struct s {
unsigned foo : 4;
unsigned : 12;
unsigned bas : 16;
};

struct t {
unsigned foo : 4;
unsigned hidden : 12;
unsigned bas : 16;
};

union s_and_t {
struct s s;
struct t t;
} s_and_t;

/* now using s_and_t.t.hidden will access */
/* the unnamed bit-field in s_and_t.s */

Furthermore this technique could be useful in implementing a
semi-opaque type, using one type as the public type, and another
type to access the "hidden" members.


> > If we have
> >
> > struct s x, y;
> > memset( &y, 0, sizeof y );
> > x = y;
> >
> > is the unnamed bit-field member guaranteed to hold zeroes, or
> > not?
>
> In y, yes, but they're irrelevant; in x, they're not even guaranteed to
> be zero.

In fact I think they are. I can't find any provision in the
Standard that suggests they needn't be copied along with every
other member. There is one case where unnamed bit-fields are
handled differently, and that is initialization. 6.7.8 p 9 says:

Except where explicitly stated otherwise, for the purposes of
this subclause unnamed members of objects of structure and union
type do not participate in initialization. Unnamed members of
structure objects have indeterminate value even after
initialization.

But note 6.7.8 p 13:

The initializer for a structure or union object that has
automatic storage duration shall be either an initializer list
as described below, or a single expression that has compatible
structure or union type. In the latter case, the initial value
of the object, including unnamed members, is that of the
expression.

Considering this, and considering the absence of any statement
that says unnamed bit-fields are treated differently during
assignment, I propose the most reasonable conclusion is that the
Standard expects them to be copied just as other members are.


> > (because structures are not allowed to have padding at the beginning)?
>
> Structures are not allowed to have _implementation-inserted_ padding
> _bytes_ at the beginning. You, as the user-programmer, are allowed to
> add as much padding of your own as pleases you. There is nothing in the
> Standard to stop you from declaring
>
> struct t {
> unsigned char padding[37];
> long int single_data_member;
> unsigned char more_padding[51];
> }
>
> Do not be surprised to find extra padding added after _your_ member
> called padding, and before or after more_padding.

I admit, my question here is to a degree deliberately obtuse.
However, there's an important difference between the question
that I asked and the example "padding" members in the example
above, in that there is nothing in the Standard that suggests
that it would put the latter under the label of 'padding', whereas
as there is a _hint_ of such suggestion for unnamed bit-fields.
(A footnote in 6.7.2.1 p 11.) I don't really think this
means that unnamed bit-fields are padding the sense that
normative passages in the Standard use the term, but
certainly we should expect the Standard to be consistent
as to its viewpoint on this question. Shouldn't we?


> Tell me, did you _really_ not know all this, or are you being an awkward
> arsehole just to make the point that you _can_ be an awkward arsehole?

I usually don't think of myself as an ass**** (either awkward or
otherwise), but if/when I do there doesn't seem to be any point to
making a statement solely for the purpose of pointing that out.

In this particular case, there are several points that I think
are of general interest to newsgroup readers. One: is structure
assignment required to copy unnamed bit-fields? (I believe it
is, other people may have different opinions.) Two: there is a
portable way to access values of bit-field members. Three: the
word 'padding' is used in several different senses in the
Standard, mostly without any definition, and in fact it's not
clear how many different senses there are, or which ones are
which in all cases. So, when making a statement about padding in
comp.lang.c, it's a good idea to be clear about which sense of
the word one is referencing, especially if it's different from,
or might be different from, the several ways that the Standard
uses the term.

Tim Rentsch

unread,
Jun 25, 2009, 1:27:07 PM6/25/09
to
Keith Thompson <ks...@mib.org> writes:

There is also the footnote in 6.2.6.1 p 6, which mentions "padding
bits", presumably meaning to cover "padding bytes" for structs/unions,
and also the unused bits between (or after) members when one of
them is a bit-field. (Of course, "padding bytes" also covers
extra bytes at the end of a union.)

Tim Rentsch

unread,
Jun 25, 2009, 1:52:06 PM6/25/09
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> ral...@xs4all.nl (Richard Bos) writes:
>
> > Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> >

> > > [long and seemingly obtuse response comments]


> >
> > Tell me, did you _really_ not know all this, or are you being an awkward
> > arsehole just to make the point that you _can_ be an awkward
> > arsehole?
>
> What on Earth is the point of being rude?

I took the question to mean that he didn't see the point of what
I was saying, and since he didn't expect me to behave in such a
pointless way, was confused about whether I'd turned stupid or
was deliberately yanking his chain. In a way it says something
good that (apparently) he considers both relatively unlikely.

In this case his comment served a useful purpose in that it let
me know he was confused about the point of my response, and that
let me respond to it more appropriately. Also, I confess that I
have been guilty of similar comments responding to other people
in the past, so I think it's only fair to forgive such comments
when they are said to me. Anyway, no worries on my part.

> Tim seems to be someone [...snip...]

Thank you for the implied compliment (at least I took it as such)
on my newsgroup postings.

Keith Thompson

unread,
Jun 25, 2009, 2:49:53 PM6/25/09
to
Tim Rentsch <t...@alumnus.caltech.edu> writes:
[...]

> Three: the
> word 'padding' is used in several different senses in the
> Standard, mostly without any definition, and in fact it's not
> clear how many different senses there are, or which ones are
> which in all cases.

As far as I can tell, the standard is *mostly* consistent about
using the term "padding" only to refer to "padding bits", which occur
within an integer representation, and "padding bytes", which occur in
a struct or union representation. (I'm not sure what it says about
the gaps between bit fields; I'll look into that later.)

A footnote in 6.7.2.1p11 says:

An unnamed bit-field structure member is useful for padding to
conform to externally imposed layouts.

and 7.19 talks about "padding" streams with spaces or null characters.

> So, when making a statement about padding in
> comp.lang.c, it's a good idea to be clear about which sense of
> the word one is referencing, especially if it's different from,
> or might be different from, the several ways that the Standard
> uses the term.

Agreed.

Keith Thompson

unread,
Jun 25, 2009, 2:59:25 PM6/25/09
to
Tim Rentsch <t...@alumnus.caltech.edu> writes:
> Keith Thompson <ks...@mib.org> writes:
[...]

>> There are at least three distinct meanings of "padding".
>>
>> The C standard defines "padding bits" for integer types, and "padding
>> bytes" for structs. (It doesn't define padding for floating-point or
>> pointer types, because it doesn't specify enough about either for the
>> concept to be meaningful -- though I suppose it could do so for FP.)
>>
>> What we're talking about here is what "padding" means in a non-C
>> context. I know of no rigorous definition (say, one that excludes
>> foam rubber), and no way to resolve any disagreements about whether an
>> unused byte in an IP packet qualifies as "padding".
>
> There is also the footnote in 6.2.6.1 p 6, which mentions "padding
> bits", presumably meaning to cover "padding bytes" for structs/unions,
> and also the unused bits between (or after) members when one of
> them is a bit-field. (Of course, "padding bytes" also covers
> extra bytes at the end of a union.)

Hmm. I suspect that was a typo for "padding bytes".

Here's the context:

When a value is stored in an object of structure or union type,
including in a member object, the bytes of the object
representation that correspond to any padding bytes take
unspecified values.

[footnote]
Thus, for example, structure assignment need not copy any padding
bits.

The quoted footnote is from N1256. In the original C99 standard, the
foonote says:

Thus, for example, structure assignment may be implemented
element-at-a-time or via memcpy.

The change was made in TC2 in response to DR #222
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_222.htm>. The
wording of the footnote in N1256 matches the wording in both DR #222
and TC2.

Tim Rentsch

unread,
Jun 26, 2009, 12:15:06 PM6/26/09
to
Keith Thompson <ks...@mib.org> writes:

> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> [...]
> > Three: the
> > word 'padding' is used in several different senses in the
> > Standard, mostly without any definition, and in fact it's not
> > clear how many different senses there are, or which ones are
> > which in all cases.
>
> As far as I can tell, the standard is *mostly* consistent about
> using the term "padding" only to refer to "padding bits", which occur
> within an integer representation, and "padding bytes", which occur in
> a struct or union representation. (I'm not sure what it says about
> the gaps between bit fields; I'll look into that later.)
>
> A footnote in 6.7.2.1p11 says:
>
> An unnamed bit-field structure member is useful for padding to
> conform to externally imposed layouts.
>
> and 7.19 talks about "padding" streams with spaces or null characters.

I think you're right about "padding bits", which AFAICS is used
almost exclusively in connection with representation of integer
types. There is one exception in a footnote in 6.2.6.1 p 6,
talking about structure assignment.

For other uses, I think it's less clear. I find only one use of
the term "padding bytes" (coincidentally also in 6.2.6.1p6). All
other uses of the term padding (not counting the "padding bits"
cases) just say padding, not padding bytes. That actually seems
more sensible, since padding in between structure members can be
either bits or bytes. It is true that uses of "padding" not
counting the "padding bits" for integer types are almost all
given in connection with struct/union types (the exception
mentioned above in connection with streams is the only one
I'm aware of). But mostly other uses of "padding" seem to
mean unused memory, _either_ bits or bytes, after struct/union
members (and possibly before subsequent members in the case
of a struct).

Tim Rentsch

unread,
Jun 26, 2009, 12:24:34 PM6/26/09
to
Keith Thompson <ks...@mib.org> writes:

It seems more likely that "padding bits" is what was
actually meant, meaning to cover both the cases of
whole bytes in between members, and also partial
bytes (bits) in between members.

But it raises an interesting question. If there is
a partial byte of unused memory (following a bit-field
member, and before the subsequent member), are those
bits guaranteed to be left unchanged by assignment
to the bit-field member (or other members, but that's
the obvious one)? Those bits don't correspond to
any padding bytes, and so aren't covered by 6.2.6.1p6.

Keith Thompson

unread,
Jun 26, 2009, 12:41:34 PM6/26/09
to
Tim Rentsch <t...@alumnus.caltech.edu> writes:
> Keith Thompson <ks...@mib.org> writes:
>> Tim Rentsch <t...@alumnus.caltech.edu> writes:
[...]
>> > There is also the footnote in 6.2.6.1 p 6, which mentions "padding
>> > bits", presumably meaning to cover "padding bytes" for structs/unions,
>> > and also the unused bits between (or after) members when one of
>> > them is a bit-field. (Of course, "padding bytes" also covers
>> > extra bytes at the end of a union.)
>>
>> Hmm. I suspect that was a typo for "padding bytes".
[...]

> It seems more likely that "padding bits" is what was
> actually meant, meaning to cover both the cases of
> whole bytes in between members, and also partial
> bytes (bits) in between members.

But the phrase "padding bits" is specifically used to refer certain
bits in integer representations. Even if "padding bits" is what was
meant here, there needs to be some more wording clarifying just what
that means.

> But it raises an interesting question. If there is
> a partial byte of unused memory (following a bit-field
> member, and before the subsequent member), are those
> bits guaranteed to be left unchanged by assignment
> to the bit-field member (or other members, but that's
> the obvious one)? Those bits don't correspond to
> any padding bytes, and so aren't covered by 6.2.6.1p6.

I don't think there'd be any benefit in guaranteeing that such bits
are unchanged. On the other hand, an implementation would have to go
out of its way to leave such bits undefined. On the other other hand,
it might make sense to do so; for example, an implementation might try
to guarantee that all padding is set to zero (unless you use something
like memset to set it to something else).

Tim Rentsch

unread,
Jun 26, 2009, 4:10:22 PM6/26/09
to
Keith Thompson <ks...@mib.org> writes:

> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> > Keith Thompson <ks...@mib.org> writes:
> >> Tim Rentsch <t...@alumnus.caltech.edu> writes:
> [...]
> >> > There is also the footnote in 6.2.6.1 p 6, which mentions "padding
> >> > bits", presumably meaning to cover "padding bytes" for structs/unions,
> >> > and also the unused bits between (or after) members when one of
> >> > them is a bit-field. (Of course, "padding bytes" also covers
> >> > extra bytes at the end of a union.)
> >>
> >> Hmm. I suspect that was a typo for "padding bytes".
> [...]
> > It seems more likely that "padding bits" is what was
> > actually meant, meaning to cover both the cases of
> > whole bytes in between members, and also partial
> > bytes (bits) in between members.
>
> But the phrase "padding bits" is specifically used to refer certain
> bits in integer representations. Even if "padding bits" is what was
> meant here, there needs to be some more wording clarifying just what
> that means.

I agree, absolutely.


> > But it raises an interesting question. If there is
> > a partial byte of unused memory (following a bit-field
> > member, and before the subsequent member), are those
> > bits guaranteed to be left unchanged by assignment
> > to the bit-field member (or other members, but that's
> > the obvious one)? Those bits don't correspond to
> > any padding bytes, and so aren't covered by 6.2.6.1p6.
>
> I don't think there'd be any benefit in guaranteeing that such bits
> are unchanged. On the other hand, an implementation would have to go
> out of its way to leave such bits undefined. On the other other hand,
> it might make sense to do so; for example, an implementation might try
> to guarantee that all padding is set to zero (unless you use something
> like memset to set it to something else).

If I had to bet (at even money, presumably) on how
the committee would vote on this question, I would
bet the vote would go in favor of having the values
of unused bits (with less than a byte's worth)
having unspecified values. (Can a single bit
even hold a trap representation?)

However, I meant only to ask the question of what
the Standard currently does say on the question, not
what it should say.

Richard Bos

unread,
Jul 5, 2009, 7:31:52 AM7/5/09
to
Tim Rentsch <t...@alumnus.caltech.edu> wrote:

> ral...@xs4all.nl (Richard Bos) writes:
>
> > Do not be surprised to find extra padding added after _your_ member
> > called padding, and before or after more_padding.
>
> I admit, my question here is to a degree deliberately obtuse.

> > Tell me, did you _really_ not know all this, or are you being an awkward


> > arsehole just to make the point that you _can_ be an awkward arsehole?
>
> I usually don't think of myself as an ass**** (either awkward or
> otherwise), but if/when I do there doesn't seem to be any point to
> making a statement solely for the purpose of pointing that out.

Well, I'm sorry, but I find post-modernism only extremely irritating in
a lit crit context, but downright anathema in a computing discussion. So
don't expect me to take it seriously.

Richard

Richard Bos

unread,
Jul 5, 2009, 7:31:51 AM7/5/09
to
Keith Thompson <ks...@mib.org> wrote:

> ral...@xs4all.nl (Richard Bos) writes:
> > Eric Sosman <eso...@ieee-dot-org.invalid> wrote:
> >> Richard Bos wrote:
> >> > What's more, padding is never a data member at all. The defining
> >> > characteristic of padding is that it exists because of the space it
> >> > takes, not because of the value it may or may even never have. Any data
> >> > member, even a data member only few people find useful, should at some
> >> > point in its life have a value that those people want to refer to.
> >> > Padding may change randomly or never at all, and you can blot over it
> >> > without affecting anyone.
> >>
> >> So I guess you'd say "unused; must be zero" bits are
> >> not padding?
> >
> > That depends on whether that is a political or a technical "must". If
> > there is reasonable expectation that it may in the future be used, and
> > can then get other values, it's not. If it's only required to be zero
> > out of a show of future planning, it's padding. I admit that this may,
> > for an outsider, be difficult to judge.
>
> There are at least three distinct meanings of "padding".
>
> The C standard defines "padding bits" for integer types, and "padding
> bytes" for structs.

As far as I can tell, both of those fall under my definition of padding
above. In neither case is the contents of those bits relevant to the
programmer.

> What we're talking about here is what "padding" means in a non-C
> context. I know of no rigorous definition (say, one that excludes
> foam rubber), and no way to resolve any disagreements about whether an
> unused byte in an IP packet qualifies as "padding".

If it's actually unused, again, I think that falls under the above
definition of "a member whose only important feature is its size, and
whose contents is irrelevant".

Richard

Tim Rentsch

unread,
Jul 8, 2009, 2:15:02 PM7/8/09
to
ral...@xs4all.nl (Richard Bos) writes:

I see you ignored all the technical content of my message
(82 lines) and chose to focus instead on just the four
lines quoted above (three of which are there only because
of your previous somewhat rudely phrased question). In
the earlier case it seemed right to give you the benefit
of the doubt. The doubt is now removed; clearly what I
should expect in the future is that you might ignore any
statement at any time whenever it suits your purposes.

Nick Keighley

unread,
Jul 9, 2009, 3:25:00 AM7/9/09
to
On 25 June, 18:20, Tim Rentsch <t...@alumnus.caltech.edu> wrote:

> ralt...@xs4all.nl (Richard Bos) writes:
> > Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> > > ralt...@xs4all.nl (Richard Bos) writes:


> > > > What's more, padding is never a data member at all. The defining
> > > > characteristic of padding is that it exists because of the space it
> > > > takes, not because of the value it may or may even never have. Any data
> > > > member, even a data member only few people find useful, should at some
> > > > point in its life have a value that those people want to refer to.
> > > > Padding may change randomly or never at all, and you can blot over it
> > > > without affecting anyone.
>
> > > In
>
> > >     struct s {
> > >       unsigned foo : 4;
> > >       unsigned     : 12;
> > >       unsigned bas : 16;
> > >     };
>
> > > would you say the data member between foo and bas is there as
> > > padding?

I might, if say I was describing the format of a data packet.
I don't consider it "padding" in the C sense of the word.

> > Since you can't access its value at all (stupid tricks with unsigned
> > char pointers aside), and that value is therefore irrelevant, yes.

I think the "stupid trick" with unsigned char can't be ignored.

> C trivia question:  Is it possible to access the value of an unnamed
> bit-field in a way that's portable and not implementation dependent?

no. Its very position is implementation defined

> Answer:  of course there are implementation dependent ways (besides
> using unsigned chars, there are other kinds of type punning, or
> reading/writing a binary file), but it may surprise some people to
> know that there is also a portable way to do so:

surprise me

>     struct s {
>         unsigned foo : 4;
>         unsigned     : 12;
>         unsigned bas : 16;
>     };
>
>     struct t {
>         unsigned foo    : 4;
>         unsigned hidden : 12;
>         unsigned bas    : 16;
>     };
>
>     union s_and_t {
>         struct s s;
>         struct t t;
>     } s_and_t;
>
>     /* now using   s_and_t.t.hidden   will access */
>     /* the unnamed bit-field in   s_and_t.s        */

...and invoke Undefined Behaviour. You've replaced IB with UB.


<snip>

Tim Rentsch

unread,
Jul 9, 2009, 6:30:34 AM7/9/09
to
Nick Keighley <nick_keigh...@hotmail.com> writes:

No, this is defined behavior, not undefined behavior.
Please see 6.5.2.3 p 5.

Nick Keighley

unread,
Jul 9, 2009, 9:31:39 AM7/9/09
to
On 9 July, 11:30, Tim Rentsch <t...@alumnus.caltech.edu> wrote:

what's the section titled, "Structure and Union Members"?
Or could you quote it? I don't have an ISO standard handy.

This is the "common initial sequence" bit? Interesting.

Richard Bos

unread,
Jul 10, 2009, 5:32:29 PM7/10/09
to
Tim Rentsch <t...@alumnus.caltech.edu> wrote:

> ral...@xs4all.nl (Richard Bos) writes:
>
> > Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> >
> > > ral...@xs4all.nl (Richard Bos) writes:
> > >
> > > > Do not be surprised to find extra padding added after _your_ member
> > > > called padding, and before or after more_padding.
> > >
> > > I admit, my question here is to a degree deliberately obtuse.
> >
> > > > Tell me, did you _really_ not know all this, or are you being an awkward
> > > > arsehole just to make the point that you _can_ be an awkward arsehole?
> > >
> > > I usually don't think of myself as an ass**** (either awkward or
> > > otherwise), but if/when I do there doesn't seem to be any point to
> > > making a statement solely for the purpose of pointing that out.
> >
> > Well, I'm sorry, but I find post-modernism only extremely irritating in
> > a lit crit context, but downright anathema in a computing discussion. So
> > don't expect me to take it seriously.
>
> I see you ignored all the technical content of my message
> (82 lines) and chose to focus instead on just the four
> lines quoted above

Yes, for exactly the reasons outlined above. I have better things to do
with my time than dragging someone's honest intentions out of them like
so many horse's teeth. You do not make a good Socrates, and while you
would probably make a good Derrida, I do not see this as a goal to be
encouraged. I'll pay attention to you again when you have not only
technical content, but also a discernable point.

Richard

Tim Rentsch

unread,
Jul 11, 2009, 1:52:32 AM7/11/09
to
Nick Keighley <nick_keigh...@hotmail.com> writes:

> On 9 July, 11:30, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> > Nick Keighley <nick_keighley_nos...@hotmail.com> writes:
> > > On 25 June, 18:20, Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> > > > ralt...@xs4all.nl (Richard Bos) writes:
> > > > > Tim Rentsch <t...@alumnus.caltech.edu> wrote:
> > > > > > ralt...@xs4all.nl (Richard Bos) writes:
> >

> > > > > > > What's more, padding is never a data member at all. The definin=
> g
> > > > > > > characteristic of padding is that it exists because of the spac=
> e it
> > > > > > > takes, not because of the value it may or may even never have. =
> Any data
> > > > > > > member, even a data member only few people find useful, should =
> at some
> > > > > > > point in its life have a value that those people want to refer =
> to.
> > > > > > > Padding may change randomly or never at all, and you can blot o=


> ver it
> > > > > > > without affecting anyone.
> >
> > > > > > In
> >
> > > > > > struct s {
> > > > > > unsigned foo : 4;
> > > > > > unsigned : 12;
> > > > > > unsigned bas : 16;
> > > > > > };
> >
> > > > > > would you say the data member between foo and bas is there as
> > > > > > padding?
> >
> > > I might, if say I was describing the format of a data packet.
> > > I don't consider it "padding" in the C sense of the word.
> >

> > > > > Since you can't access its value at all (stupid tricks with unsigne=


> d
> > > > > char pointers aside), and that value is therefore irrelevant, yes.
> >
> > > I think the "stupid trick" with unsigned char can't be ignored.
> >

> > > > C trivia question: Is it possible to access the value of an unname=

Yes, the common initial sequence guarantee. Here is the text of
paragraph 5:

One special guarantee is made in order to simplify the use
of unions: if a union contains several structures that
share a common initial sequence (see below), and if the
union object currently contains one of these structures, it
is permitted to inspect the common initial part of any of
them anywhere that a declaration of the complete type of the
union is visible. Two structures share a common initial
sequence if corresponding members have compatible types
(and, for bit-fields, the same widths) for a sequence of one
or more initial members.

0 new messages