Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #9776 > unrolled thread
| Started by | Quentin Pope <qp19433@hotmail.NOSPAM.com> |
|---|---|
| First post | 2011-08-31 21:23 +0000 |
| Last post | 2011-09-01 16:27 -0700 |
| Articles | 20 on this page of 31 — 17 participants |
Back to article view | Back to comp.lang.c
Bit-field union bug Quentin Pope <qp19433@hotmail.NOSPAM.com> - 2011-08-31 21:23 +0000
Re: Bit-field union bug Keith Thompson <kst-u@mib.org> - 2011-08-31 14:34 -0700
Re: Bit-field union bug Quentin Pope <qp19433@hotmail.NOSPAM.com> - 2011-09-03 19:06 +0000
Re: Bit-field union bug Ian Collins <ian-news@hotmail.com> - 2011-09-04 08:19 +1200
Re: Bit-field union bug Quentin Pope <qp19433@hotmail.NOSPAM.com> - 2011-09-03 21:12 +0000
Re: Bit-field union bug Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-03 22:30 +0100
Re: Bit-field union bug Ian Collins <ian-news@hotmail.com> - 2011-09-04 11:01 +1200
Re: Bit-field union bug Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-04 00:37 +0100
Re: Bit-field union bug Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-06 00:36 +0300
Re: Bit-field union bug Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 12:23 -0800
Re: Bit-field union bug Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-24 21:15 +0000
Re: Bit-field union bug Ian Collins <ian-news@hotmail.com> - 2011-09-01 09:36 +1200
Re: Bit-field union bug jacob navia <jacob@spamsink.net> - 2011-08-31 23:38 +0200
Re: Bit-field union bug Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-08-31 15:42 -0600
Re: Bit-field union bug Seebs <usenet-nospam@seebs.net> - 2011-08-31 21:57 +0000
Re: Bit-field union bug James Kuyper <jameskuyper@verizon.net> - 2011-08-31 18:21 -0400
Re: Bit-field union bug Seebs <usenet-nospam@seebs.net> - 2011-09-01 02:45 +0000
Re: Bit-field union bug James Kuyper <jameskuyper@verizon.net> - 2011-09-01 06:37 -0400
Re: Bit-field union bug Kenneth Brody <kenbrody@spamcop.net> - 2011-09-01 14:19 -0400
Re: Bit-field union bug James Kuyper <jameskuyper@verizon.net> - 2011-09-01 14:46 -0400
Re: Bit-field union bug Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-01 15:34 +0300
Re: Bit-field union bug Keith Thompson <kst-u@mib.org> - 2011-09-01 07:24 -0700
Re: Bit-field union bug James Kuyper <jameskuyper@verizon.net> - 2011-08-31 17:55 -0400
Re: Bit-field union bug "Scott Fluhrer" <sfluhrer@ix.netcom.com> - 2011-08-31 19:01 -0400
Re: Bit-field union bug Peter Nilsson <airia@acay.com.au> - 2011-08-31 16:03 -0700
Re: Bit-field union bug David Thompson <dave.thompson2@verizon.net> - 2011-09-06 01:13 -0400
Re: Bit-field union bug Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 12:17 -0800
Re: Bit-field union bug ec429 <ec429@cam.ac.uk> - 2012-01-25 00:13 +0000
Re: Bit-field union bug Kaz Kylheku <kaz@kylheku.com> - 2012-01-25 00:36 +0000
Re: Bit-field union bug Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-31 14:54 -0800
Re: Bit-field union bug Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-09-01 16:27 -0700
Page 1 of 2 [1] 2 Next page →
| From | Quentin Pope <qp19433@hotmail.NOSPAM.com> |
|---|---|
| Date | 2011-08-31 21:23 +0000 |
| Subject | Bit-field union bug |
| Message-ID | <j3m8np$8gv$1@speranza.aioe.org> |
On my compiler, the output of "sizeof(foo)" of the following is 8,
instead of 4.
Which indicates that the compiler is aligning the union at
the next int boundary, rather than coalescing it with "proto".
I think this is a bug.
struct s_skip_ind {
unsigned skip_ind:4;
};
struct s_trans_id {
unsigned trans_val:3;
unsigned trans_id:1;
};
struct foo {
unsigned proto:4;
union {
s_skip_ind skip_ind;
s_trans_id trans_id;
};
};
[toc] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-08-31 14:34 -0700 |
| Message-ID | <ln62ldtgdq.fsf@nuthaus.mib.org> |
| In reply to | #9776 |
Quentin Pope <qp19433@hotmail.NOSPAM.com> writes:
> On my compiler, the output of "sizeof(foo)" of the following is 8,
> instead of 4.
>
> Which indicates that the compiler is aligning the union at
> the next int boundary, rather than coalescing it with "proto".
>
> I think this is a bug.
>
>
> struct s_skip_ind {
> unsigned skip_ind:4;
> };
>
> struct s_trans_id {
> unsigned trans_val:3;
> unsigned trans_id:1;
> };
>
> struct foo {
> unsigned proto:4;
> union {
> s_skip_ind skip_ind;
> s_trans_id trans_id;
> };
> };
Whether it's a bug or not, it's not a violation of the C standard.
Compilers can legally insert arbitrary padding between any two members
of a struct, or after the last one.
I think I've seen some compilers that use the declared type of a bit
field to determine its alignment; for example, given
unsigned char x:1
unsigned short y:1
unsigned int z:1
x, y, and z might be aligned on 1-byte, 2-byte, and 4-byte boundaries,
respectively. I don't think there's any support for this in the
standard, which only requires support for bit fields of types int,
signed int, unsigned int, and (new in C99) _Bool.
--
Keith Thompson (The_Other_Keith) kst-u@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"
[toc] | [prev] | [next] | [standalone]
| From | Quentin Pope <qp19433@hotmail.NOSPAM.com> |
|---|---|
| Date | 2011-09-03 19:06 +0000 |
| Message-ID | <j3ttr8$uil$1@speranza.aioe.org> |
| In reply to | #9777 |
On Wed, 31 Aug 2011 14:34:09 -0700, Keith Thompson wrote:
> Quentin Pope <qp19433@hotmail.NOSPAM.com> writes:
>> On my compiler, the output of "sizeof(foo)" of the following is 8,
>> instead of 4.
>>
>> Which indicates that the compiler is aligning the union at the next int
>> boundary, rather than coalescing it with "proto".
>>
>> I think this is a bug.
>>
>>
>> struct s_skip_ind {
>> unsigned skip_ind:4;
>> };
>>
>> struct s_trans_id {
>> unsigned trans_val:3;
>> unsigned trans_id:1;
>> };
>>
>> struct foo {
>> unsigned proto:4;
>> union {
>> s_skip_ind skip_ind;
>> s_trans_id trans_id;
>> };
>> };
>
> Whether it's a bug or not, it's not a violation of the C standard.
> Compilers can legally insert arbitrary padding between any two members
> of a struct, or after the last one.
>
> I think I've seen some compilers that use the declared type of a bit
> field to determine its alignment; for example, given
> unsigned char x:1
> unsigned short y:1
> unsigned int z:1
> x, y, and z might be aligned on 1-byte, 2-byte, and 4-byte boundaries,
> respectively. I don't think there's any support for this in the
> standard, which only requires support for bit fields of types int,
> signed int, unsigned int, and (new in C99) _Bool.
I see.
In this case, is there an equivalent of the offsetOf() function for
bitfield members, to allow programmers to determine whether or not
bitfields have been packed?
Cheers
QP
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-09-04 08:19 +1200 |
| Message-ID | <9cfgfeFsstU3@mid.individual.net> |
| In reply to | #9918 |
On 09/ 4/11 07:06 AM, Quentin Pope wrote: > On Wed, 31 Aug 2011 14:34:09 -0700, Keith Thompson wrote: >> Quentin Pope<qp19433@hotmail.NOSPAM.com> writes: >>> On my compiler, the output of "sizeof(foo)" of the following is 8, >>> instead of 4. >>> >>> Which indicates that the compiler is aligning the union at the next int >>> boundary, rather than coalescing it with "proto". >> >> Whether it's a bug or not, it's not a violation of the C standard. >> Compilers can legally insert arbitrary padding between any two members >> of a struct, or after the last one. >> >> I think I've seen some compilers that use the declared type of a bit >> field to determine its alignment; for example, given >> unsigned char x:1 >> unsigned short y:1 >> unsigned int z:1 >> x, y, and z might be aligned on 1-byte, 2-byte, and 4-byte boundaries, >> respectively. I don't think there's any support for this in the >> standard, which only requires support for bit fields of types int, >> signed int, unsigned int, and (new in C99) _Bool. > > I see. > > In this case, is there an equivalent of the offsetOf() function for > bitfield members, to allow programmers to determine whether or not > bitfields have been packed? Won't the sizeof operator tell you? -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Quentin Pope <qp19433@hotmail.NOSPAM.com> |
|---|---|
| Date | 2011-09-03 21:12 +0000 |
| Message-ID | <j3u573$h5b$1@speranza.aioe.org> |
| In reply to | #9919 |
On Sun, 04 Sep 2011 08:19:58 +1200, Ian Collins wrote:
> On 09/ 4/11 07:06 AM, Quentin Pope wrote:
>> On Wed, 31 Aug 2011 14:34:09 -0700, Keith Thompson wrote:
>>> Quentin Pope<qp19433@hotmail.NOSPAM.com> writes:
>>>> On my compiler, the output of "sizeof(foo)" of the following is 8,
>>>> instead of 4.
>>>>
>>>> Which indicates that the compiler is aligning the union at the next
>>>> int boundary, rather than coalescing it with "proto".
>>>
>>> Whether it's a bug or not, it's not a violation of the C standard.
>>> Compilers can legally insert arbitrary padding between any two members
>>> of a struct, or after the last one.
>>>
>>> I think I've seen some compilers that use the declared type of a bit
>>> field to determine its alignment; for example, given
>>> unsigned char x:1
>>> unsigned short y:1
>>> unsigned int z:1
>>> x, y, and z might be aligned on 1-byte, 2-byte, and 4-byte boundaries,
>>> respectively. I don't think there's any support for this in the
>>> standard, which only requires support for bit fields of types int,
>>> signed int, unsigned int, and (new in C99) _Bool.
>>
>> I see.
>>
>> In this case, is there an equivalent of the offsetOf() function for
>> bitfield members, to allow programmers to determine whether or not
>> bitfields have been packed?
>
> Won't the sizeof operator tell you?
Not necessarily I don't think.
For example, imagine
struct foo {
unsigned short a:2;
unsigned short b:2;
unsigned short c:2;
unsigned short d:2;
};
If sizeOf(foo) is 3, then there is no way of telling whether a and b are
packed into 1 byte, or if it's b and c, or if it's c and d.
Cheers,
QP
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-09-03 22:30 +0100 |
| Message-ID | <0.d9fab49de2f78c213571.20110903223032BST.87zkil5n5z.fsf@bsb.me.uk> |
| In reply to | #9920 |
Quentin Pope <qp19433@hotmail.NOSPAM.com> writes:
> On Sun, 04 Sep 2011 08:19:58 +1200, Ian Collins wrote:
>> On 09/ 4/11 07:06 AM, Quentin Pope wrote:
>>> On Wed, 31 Aug 2011 14:34:09 -0700, Keith Thompson wrote:
>>>> Quentin Pope<qp19433@hotmail.NOSPAM.com> writes:
>>>>> On my compiler, the output of "sizeof(foo)" of the following is 8,
>>>>> instead of 4.
>>>>>
>>>>> Which indicates that the compiler is aligning the union at the next
>>>>> int boundary, rather than coalescing it with "proto".
>>>>
>>>> Whether it's a bug or not, it's not a violation of the C standard.
>>>> Compilers can legally insert arbitrary padding between any two members
>>>> of a struct, or after the last one.
>>>>
>>>> I think I've seen some compilers that use the declared type of a bit
>>>> field to determine its alignment; for example, given
>>>> unsigned char x:1
>>>> unsigned short y:1
>>>> unsigned int z:1
>>>> x, y, and z might be aligned on 1-byte, 2-byte, and 4-byte boundaries,
>>>> respectively. I don't think there's any support for this in the
>>>> standard, which only requires support for bit fields of types int,
>>>> signed int, unsigned int, and (new in C99) _Bool.
>>>
>>> I see.
>>>
>>> In this case, is there an equivalent of the offsetOf() function for
>>> bitfield members, to allow programmers to determine whether or not
>>> bitfields have been packed?
>>
>> Won't the sizeof operator tell you?
>
> Not necessarily I don't think.
>
> For example, imagine
> struct foo {
> unsigned short a:2;
> unsigned short b:2;
> unsigned short c:2;
> unsigned short d:2;
> };
>
> If sizeOf(foo) is 3, then there is no way of telling whether a and b are
> packed into 1 byte, or if it's b and c, or if it's c and d.
Your point is valid but the example is not a good one. First, by using
unsigned short you've gone outside of standard C -- anything is
possible. If you were to replace short with int, then you would get
much more than think you might think you do:
In the "unsigned int" version, the C standard says that a, b, c and d
must be packed together, consecutively, in the first byte of the struct.
The "addressable storage unit" into which they get packed can't be less
than 1 byte in size and a byte can't be less than 8 bits wide. Which
one goes in the high-significance position is not specified but it is
must be either a or d and the other must follow in order.
However, I think it is often the case that code that needs to know how
bit fields are packed is using them beyond their natural purpose.
Shifting and masking gives you far more control over how things pack and
is usually the way to go when it matters.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-09-04 11:01 +1200 |
| Message-ID | <9cfpu1FsstU4@mid.individual.net> |
| In reply to | #9921 |
On 09/ 4/11 09:30 AM, Ben Bacarisse wrote: > > However, I think it is often the case that code that needs to know how > bit fields are packed is using them beyond their natural purpose. > Shifting and masking gives you far more control over how things pack and > is usually the way to go when it matters. Or the code is written based on knowledge of the compiler being used. I have often used bit fields to map hardware registers or bits in messages headers. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-09-04 00:37 +0100 |
| Message-ID | <0.fa7feb432434a3a5f022.20110904003740BST.87ty8t5ha3.fsf@bsb.me.uk> |
| In reply to | #9922 |
Ian Collins <ian-news@hotmail.com> writes: > On 09/ 4/11 09:30 AM, Ben Bacarisse wrote: >> >> However, I think it is often the case that code that needs to know how >> bit fields are packed is using them beyond their natural purpose. >> Shifting and masking gives you far more control over how things pack and >> is usually the way to go when it matters. > > Or the code is written based on knowledge of the compiler being used. > I have often used bit fields to map hardware registers or bits in > messages headers. Absolutely. Hence "often" and "usually". If you can rely on the compiler maintaining the layout you need there is no problem. None the less, bit fields seem to have a fascination for people learning C that makes them dangerously seductive. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-09-06 00:36 +0300 |
| Message-ID | <87pqje658m.fsf@bazspaz.fatphil.org> |
| In reply to | #9923 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > Ian Collins <ian-news@hotmail.com> writes: > > > On 09/ 4/11 09:30 AM, Ben Bacarisse wrote: > >> > >> However, I think it is often the case that code that needs to know how > >> bit fields are packed is using them beyond their natural purpose. > >> Shifting and masking gives you far more control over how things pack and > >> is usually the way to go when it matters. > > > > Or the code is written based on knowledge of the compiler being used. > > I have often used bit fields to map hardware registers or bits in > > messages headers. > > Absolutely. Hence "often" and "usually". If you can rely on the > compiler maintaining the layout you need there is no problem. This warning reminds me of the lack of trust I can have in that every day: In file included from drivers/input/touchscreen/atmel_mxt.c:34: drivers/input/touchscreen/atmel_mxt_objects.h:45: note: Offset of packed bit-field 'bit' has changed in GCC 4.4 I'm not sure why there's the incompatibility, it seems a strange thing to change. Phil -- "Religion is what keeps the poor from murdering the rich." -- Napoleon
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2012-01-24 12:23 -0800 |
| Message-ID | <kfnd3a8hmt7.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #9921 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Quentin Pope <qp19433@hotmail.NOSPAM.com> writes:
>
>> [snip]
>>
>> For example, imagine
>> struct foo {
>> unsigned short a:2;
>> unsigned short b:2;
>> unsigned short c:2;
>> unsigned short d:2;
>> };
>>
>> If sizeOf(foo) is 3, then there is no way of telling whether a and b are
>> packed into 1 byte, or if it's b and c, or if it's c and d.
>
> [snip]
>
> In the "unsigned int" version, the C standard says that a, b, c and d
> must be packed together, consecutively, in the first byte of the struct.
> The "addressable storage unit" into which they get packed can't be less
> than 1 byte in size and a byte can't be less than 8 bits wide. Which
> one goes in the high-significance position is not specified but it is
> must be either a or d and the other must follow in order.
AFAIK the Standard does not require them to be in the first
byte, just the first addressable unit. For example, they
might be the low-order bits in a four byte unsigned int
on a machine that is "big endian", ie, they would be in
the fourth byte rather than the first.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-01-24 21:15 +0000 |
| Message-ID | <0.e86b040363f11709b8a6.20120124211516GMT.87pqe8hkez.fsf@bsb.me.uk> |
| In reply to | #16115 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> Quentin Pope <qp19433@hotmail.NOSPAM.com> writes:
>>
>>> [snip]
>>>
>>> For example, imagine
>>> struct foo {
>>> unsigned short a:2;
>>> unsigned short b:2;
>>> unsigned short c:2;
>>> unsigned short d:2;
>>> };
>>>
>>> If sizeOf(foo) is 3, then there is no way of telling whether a and b are
>>> packed into 1 byte, or if it's b and c, or if it's c and d.
>>
>> [snip]
>>
>> In the "unsigned int" version, the C standard says that a, b, c and d
>> must be packed together, consecutively, in the first byte of the struct.
>> The "addressable storage unit" into which they get packed can't be less
>> than 1 byte in size and a byte can't be less than 8 bits wide. Which
>> one goes in the high-significance position is not specified but it is
>> must be either a or d and the other must follow in order.
>
> AFAIK the Standard does not require them to be in the first
> byte, just the first addressable unit. For example, they
> might be the low-order bits in a four byte unsigned int
> on a machine that is "big endian", ie, they would be in
> the fourth byte rather than the first.
Yes, I think you are right. They must be packed consecutively in the
storage unit chosen by the implementation but that need not be a byte.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-09-01 09:36 +1200 |
| Message-ID | <9c7nrbF8n6U1@mid.individual.net> |
| In reply to | #9776 |
On 09/ 1/11 09:23 AM, Quentin Pope wrote:
> On my compiler, the output of "sizeof(foo)" of the following is 8,
> instead of 4.
>
> Which indicates that the compiler is aligning the union at
> the next int boundary, rather than coalescing it with "proto".
>
> I think this is a bug.
I don't. Each struct member has to be correctly aligned. There is
nothing in the standard that says adjacent bit field structs should be
coalesced.
> struct s_skip_ind {
> unsigned skip_ind:4;
> };
>
> struct s_trans_id {
> unsigned trans_val:3;
> unsigned trans_id:1;
> };
>
> struct foo {
> unsigned proto:4;
> union {
> s_skip_ind skip_ind;
struct keyword missing.
> s_trans_id trans_id;
> };
Here you have an unnamed structure member, with is isn't standard, so
the compiler could do what it likes, including ignoring it.
> };
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-08-31 23:38 +0200 |
| Message-ID | <j3m9ku$atp$1@speranza.aioe.org> |
| In reply to | #9776 |
Le 31/08/11 23:23, Quentin Pope a écrit :
> On my compiler, the output of "sizeof(foo)" of the following is 8,
> instead of 4.
>
> Which indicates that the compiler is aligning the union at
> the next int boundary, rather than coalescing it with "proto".
>
> I think this is a bug.
>
>
> struct s_skip_ind {
> unsigned skip_ind:4;
> };
>
> struct s_trans_id {
> unsigned trans_val:3;
> unsigned trans_id:1;
> };
>
> struct foo {
> unsigned proto:4;
> union {
> s_skip_ind skip_ind;
> s_trans_id trans_id;
> };
> };
Most compilers have some option to control alignment.
#pragma pack(1) (For lcc-win or Microsoft coompilers)
__attribute__((packed)) (for gcc)
Read your compiler documentation on how to control the alignment.
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2011-08-31 15:42 -0600 |
| Message-ID | <1bbov5xnp5.fsf@snowball.wb.pfeifferfamily.net> |
| In reply to | #9776 |
Quentin Pope <qp19433@hotmail.NOSPAM.com> writes:
> On my compiler, the output of "sizeof(foo)" of the following is 8,
> instead of 4.
>
> Which indicates that the compiler is aligning the union at
> the next int boundary, rather than coalescing it with "proto".
>
> I think this is a bug.
>
>
> struct s_skip_ind {
> unsigned skip_ind:4;
> };
>
> struct s_trans_id {
> unsigned trans_val:3;
> unsigned trans_id:1;
> };
>
> struct foo {
> unsigned proto:4;
> union {
> s_skip_ind skip_ind;
> s_trans_id trans_id;
> };
> };
While I would agree with you, the standard disagrees with both of us.
I'm not quite sure what the point of a bitfield is when the compiler is
free to insert arbitrary padding between elements, but that is indeed
the case.
[toc] | [prev] | [next] | [standalone]
| From | Seebs <usenet-nospam@seebs.net> |
|---|---|
| Date | 2011-08-31 21:57 +0000 |
| Message-ID | <slrnj5tbae.sup.usenet-nospam@guild.seebs.net> |
| In reply to | #9780 |
On 2011-08-31, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote: > While I would agree with you, the standard disagrees with both of us. > I'm not quite sure what the point of a bitfield is when the compiler is > free to insert arbitrary padding between elements, but that is indeed > the case. The point is that the compiler is *permitted* to coalesce bitfields. But not required to, because some systems really don't provide meaningful support for them. Basically, bitfields aren't expected to provide an absolutely reliable mapping onto a series of bits; they're expected to provide a way that you can hint that you don't need a lot of storage, such that compilers can in some cases save a few bytes. -s -- Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated! I am not speaking for my employer, although they do rent some of my opinions.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-08-31 18:21 -0400 |
| Message-ID | <4E5EB3D5.9090402@verizon.net> |
| In reply to | #9782 |
On 08/31/2011 05:57 PM, Seebs wrote: > On 2011-08-31, Joe Pfeiffer <pfeiffer@cs.nmsu.edu> wrote: >> While I would agree with you, the standard disagrees with both of us. >> I'm not quite sure what the point of a bitfield is when the compiler is >> free to insert arbitrary padding between elements, but that is indeed >> the case. > > The point is that the compiler is *permitted* to coalesce bitfields. But > not required to, because some systems really don't provide meaningful support > for them. Actually, it is required to do so, when adjacent bit-fields in the same struct fit in a single storage unit (6.7.2.1p10). And since CHAR_BIT is required to be >=8, these bit-fields, had they been in the same struct, would have been required to be stored in adjacent bits of the same storage unit. > Basically, bitfields aren't expected to provide an absolutely reliable > mapping onto a series of bits; they're expected to provide a way that you > can hint that you don't need a lot of storage, such that compilers can in > some cases save a few bytes. An implementation has a lot of freedom to allocate bit-fields; far too much to make any portable use of them for communications outside of a single program. However, there's not quite as much freedom as you thought there was.
[toc] | [prev] | [next] | [standalone]
| From | Seebs <usenet-nospam@seebs.net> |
|---|---|
| Date | 2011-09-01 02:45 +0000 |
| Message-ID | <slrnj5tj2n.11vj.usenet-nospam@guild.seebs.net> |
| In reply to | #9783 |
On 2011-08-31, James Kuyper <jameskuyper@verizon.net> wrote:
> Actually, it is required to do so, when adjacent bit-fields in the same
> struct fit in a single storage unit (6.7.2.1p10).
Thanks for the correction. I had a vague sense that there were circumstances
where it was mandatory, and I hadn't thought through that the separate
struct declarations were the problem.
In fact, so far as I can tell, it's *not* permissible to coalesce adjacent
structs.
Assume CHAR_BIT is 8.
struct a { int x:4; };
struct b { struct a a1, a2; } example_b;
If struct b coalesced the bit fields, what would the address of example_b.a2
be? The "struct a" object MUST have a size of at least 1, and it has to be
an integer size.
So you have to calculate the padding of the struct a independently, and then
use that padded object as the sub-member in other structs.
(I wonder whether that's true in Plan 9 C of anonymous structure members...)
-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-09-01 06:37 -0400 |
| Message-ID | <j3nn94$bbe$1@dont-email.me> |
| In reply to | #9793 |
On 08/31/2011 10:45 PM, Seebs wrote: > On 2011-08-31, James Kuyper <jameskuyper@verizon.net> wrote: >> Actually, it is required to do so, when adjacent bit-fields in the same >> struct fit in a single storage unit (6.7.2.1p10). ... > In fact, so far as I can tell, it's *not* permissible to coalesce adjacent > structs. Of course. That was apparently not as obvious to the OP as it seems to me. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Kenneth Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2011-09-01 14:19 -0400 |
| Message-ID | <XZudnYcMB5FbUcLTnZ2dnUVZ_v2dnZ2d@bestweb.net> |
| In reply to | #9783 |
On 8/31/2011 6:21 PM, James Kuyper wrote:
> On 08/31/2011 05:57 PM, Seebs wrote:
>> On 2011-08-31, Joe Pfeiffer<pfeiffer@cs.nmsu.edu> wrote:
>>> While I would agree with you, the standard disagrees with both of us.
>>> I'm not quite sure what the point of a bitfield is when the compiler is
>>> free to insert arbitrary padding between elements, but that is indeed
>>> the case.
>>
>> The point is that the compiler is *permitted* to coalesce bitfields. But
>> not required to, because some systems really don't provide meaningful support
>> for them.
>
> Actually, it is required to do so, when adjacent bit-fields in the same
> struct fit in a single storage unit (6.7.2.1p10). And since CHAR_BIT is
> required to be>=8, these bit-fields, had they been in the same struct,
> would have been required to be stored in adjacent bits of the same
> storage unit.
But, this is not two bit-fields. Here's the original code:
>> > struct s_skip_ind {
>> > unsigned skip_ind:4;
>> > };
>> >
>> > struct s_trans_id {
>> > unsigned trans_val:3;
>> > unsigned trans_id:1;
>> > };
>> >
>> > struct foo {
>> > unsigned proto:4;
>> > union {
>> > s_skip_ind skip_ind;
>> > s_trans_id trans_id;
>> > };
>> > };
The struct "foo" consists of a bit-field and a union. The fact that the
union consists of two structs which, in turn, consist of bit-fields, is
irrelevant to 6.7.2.1p10 (as I read it):
> If enough space remains, a bit-field that immediately follows another
> bit-field in a structure shall be packed into adjacent bits of the same
> unit.
What follows the bit-field "proto" is an unnamed union, not another bit-field.
[...]
> An implementation has a lot of freedom to allocate bit-fields; far too
> much to make any portable use of them for communications outside of a
> single program. However, there's not quite as much freedom as you
> thought there was.
As I found out years ago when a bit-mapped flags value stored on disk was
not portable to another system whose compiler allocated bit-fields the other
way.
struct foo {
...
struct {
int SomeFlag:1;
int AnotherFlag:1;
}
Flags;
...
};
It's now just an "unsigned short" with an enum for bit-mask values.
--
Kenneth Brody
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-09-01 14:46 -0400 |
| Message-ID | <4E5FD30A.8000908@verizon.net> |
| In reply to | #9830 |
On 09/01/2011 02:19 PM, Kenneth Brody wrote: > On 8/31/2011 6:21 PM, James Kuyper wrote: >> On 08/31/2011 05:57 PM, Seebs wrote: >>> On 2011-08-31, Joe Pfeiffer<pfeiffer@cs.nmsu.edu> wrote: >>>> While I would agree with you, the standard disagrees with both of us. >>>> I'm not quite sure what the point of a bitfield is when the compiler is >>>> free to insert arbitrary padding between elements, but that is indeed >>>> the case. >>> >>> The point is that the compiler is *permitted* to coalesce bitfields. But >>> not required to, because some systems really don't provide meaningful support >>> for them. >> >> Actually, it is required to do so, when adjacent bit-fields in the same >> struct fit in a single storage unit (6.7.2.1p10). And since CHAR_BIT is >> required to be>=8, these bit-fields, had they been in the same struct, >> would have been required to be stored in adjacent bits of the same >> storage unit. > > But, this is not two bit-fields. Here's the original code: I already raised that point in an earlier message. In this message I was dealing with a different point. In the case described by the OP, a compiler is prohibited from coalescing "proto" with any of the other bit-fields, because if the unnamed union member had been given a name (as it should have been), that member would have been required to have a distinct address. However, in the case which I was referring to above, "adjacent bit-fields in the same struct", it's not merely permitted to coalesce such bit-fields, it's required to do so, if it can. Either way, "permitted" was an incorrect description.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web