473,770 Members | 6,736 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

De facto standard size of bit-field objects

Although the C90 standard only mentions the use of 'signed int' and
'unsigned int' for bit-fields (use 'int' at your own risk) and C99
adds _Bool.
It seems that most compilers create the size of the bit-field object
from the size used to specify the field.

Could this be considered a defacto standard now (at least for 8 bit
sized bit-fields)?

Any recent compilers not allowing this?

struct
{
unsigned char x:4;
unsigned char y:4;
} nibs;
struct
{
unsigned int x:4;
unsigned int y:4;
} nibs;

see

http://www.keil.com/support/docs/928.htm

It refers the OP to the book
"The C Programming Language" by Kernighan & Ritchie but this book
doesn't mention using unsigned char in bit-fields.
[Soapbox]
Wouldn't it had more sense for the compiler folks to just add up the
specified number bits and use the smallest integer type that would fit
so code could follow the standard?
Obviously programmers want to use bit-field objects that may be
smaller or larger than standard integer size shouldn't the standard
support that.
(I know that one can always use masking and shifting but that isn't my
question.)
[end soapbox]

Feb 23 '07 #1
6 3851
ma*****@yahoo.c om writes:
Although the C90 standard only mentions the use of 'signed int' and
'unsigned int' for bit-fields (use 'int' at your own risk) and C99
adds _Bool.
It seems that most compilers create the size of the bit-field object
from the size used to specify the field.
Of course.
Could this be considered a defacto standard now (at least for 8 bit
sized bit-fields)?

Any recent compilers not allowing this?

struct
{
unsigned char x:4;
unsigned char y:4;
} nibs;
struct
{
unsigned int x:4;
unsigned int y:4;
} nibs;
Oh, you meant that the *type* of the bit-field determines the size.
see

http://www.keil.com/support/docs/928.htm
Apparently for that compiler the type of a bit field affects the size
of the enclosing structure (though it doesn't affect the size of the
bit field itself). In the second declaration, the structure
apparently is at least as large as unsigned int.

C99 6.7.2.1p9:

A bit-field is interpreted as a signed or unsigned integer type
consisting of the specified number of bits.

Allowing unsigned char bit fields is obviously a compiler extension.
Making a struct bigger than it needs to be based on the declared type
of a bit field, rather than its declared width, is an odd choice and
is not required, or even suggested, by the standard as far as I can
tell. (I've seen this behavior in other compilers, including gcc.)

[...]
[Soapbox]
Wouldn't it had more sense for the compiler folks to just add up the
specified number bits and use the smallest integer type that would fit
so code could follow the standard?
Obviously programmers want to use bit-field objects that may be
smaller or larger than standard integer size shouldn't the standard
support that.
(I know that one can always use masking and shifting but that isn't my
question.)
[end soapbox]
The width (":4" in the examples above) determines the size of a bit
field, not the declared type. I suggest that the compiler should be
smart enough to treat int and unsigned int bit fields properly without
wasting space. I see no need to change the standard.

Perhaps there's some sensible rationale for this behavior, but I'm not
seeing it.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 23 '07 #2
Keith Thompson wrote:
ma*****@yahoo.c om writes:
>>struct
{
unsigned char x:4;
unsigned char y:4;
} nibs;
...
http://www.keil.com/support/docs/928.htm

Apparently for that compiler the type of a bit field affects the size
of the enclosing structure (though it doesn't affect the size of the
bit field itself). In the second declaration, the structure
apparently is at least as large as unsigned int.
...
Allowing unsigned char bit fields is obviously a compiler extension.
Making a struct bigger than it needs to be based on the declared type
of a bit field, rather than its declared width, is an odd choice and
is not required, or even suggested, by the standard as far as I can
tell. (I've seen this behavior in other compilers, including gcc.)
...
The width (":4" in the examples above) determines the size of a bit
field, not the declared type. I suggest that the compiler should be
smart enough to treat int and unsigned int bit fields properly without
wasting space. I see no need to change the standard.

Perhaps there's some sensible rationale for this behavior, but I'm not
seeing it.
The rationale, I think, is to be compatible with other compilers that
set the minimum size for a struct containing bit fields as the size of
an int. The extension, then, provides that compatibility and allows
generating a minimum-size struct.

That said, I think that the int-size minimum and compatibility attempt
are wrong-headed. I agree that compilers should use the minimum size of
a struct unless that causes a penalty somewhere.

--
Thad
Feb 24 '07 #3

On Fri, 23 Feb 2007 ma*****@yahoo.c om wrote:
>
Although the C90 standard only mentions the use of 'signed int' and
'unsigned int' for bit-fields (use 'int' at your own risk) and C99
adds _Bool.
It seems that most compilers create the size of the bit-field object
from the size used to specify the field.

Could this be considered a defacto standard now (at least for 8 bit
sized bit-fields)?
I don't exactly see what you mean. I think you are saying that on
"most" compilers, the structure definition
struct {
unsigned char x:4;
unsigned char y:4;
} nibs;
yields a struct with a size of 8 bits, arranged as xxxxyyyy, but
struct {
unsigned int x:4;
unsigned int y:4;
} nibs;
yields a struct with a size of 32 bits, arranged as
xxxxyyyy0000000 000000000000000 00.

This is indeed true for Keil's compiler:
http://www.keil.com/support/docs/928.htm
and GCC and yes, probably most modern compilers. However, there's
an extra wrinkle that you didn't mention: On "most" compilers, a
bitfield of declared type T will never span memory chunks of
size T. (The real type of a bitfield is simply a "bit-field type"; but
like you, I'm talking about the "unsigned char" or whatever that you
use in the struct definition.)
For example, an "unsigned char" bitfield will never span two bytes;
padding bits will be inserted if necessary to justify it in its own
byte. Therefore, the struct definition

struct {
unsigned char x : 5;
unsigned char y : 5;
} nabs;

will correspond on "most" compilers to xxxxx000yyyyy00 0, while

struct {
unsigned short x : 5;
unsigned short y : 5;
} nabs;

will correspond to xxxxxyyyyy00000 0.

[Soapbox]
Wouldn't it had more sense for the compiler folks to just add up the
specified number bits and use the smallest integer type that would fit
so code could follow the standard?
It would make about as much sense, I guess. I don't see how it would
make /more/ sense. If you care about that kind of micro-optimization,
you probably welcome the extra tiny bit of control over alignment given
to you by the "de-facto" standard.
The issue may originally have been that unaligned memory accesses are
terribly slow on most platforms; therefore, it makes sense to allow the
programmer to force byte-alignment or word-alignment with a minimum of
fuss. (C99 introduced anonymous bitfields to deal with the same issue.)
The issue now is certainly compatibility with other compilers. Peer
pressure is a strong force in the compiler field.

N869 section 6.7.2.1#9 seems to encourage the "de-facto" behavior:

[#9] An implementation may allocate any addressable storage
unit large enough to hold a bit-field. 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. If insufficient space remains, whether a
bit-field that does not fit is put into the next unit or
overlaps adjacent units is implementation-defined. The
order of allocation of bit-fields within a unit (high-order
to low-order or low-order to high-order) is implementation-
defined. The alignment of the addressable storage unit is
unspecified.
Obviously programmers want to use bit-field objects that may be
smaller or larger than standard integer size shouldn't the standard
support that.
No. If there's no Standard support for 128-bit integer math, it
seems pretty silly to require implementations to support integer
math on bitfields of type "signed int foo : 128". That would put a
huge burden on implementors to deal with arbitrarily-wide integer
math, while making users jump through silly hoops to get at it.

Some compilers support "long long" bitfields. Interestingly, GCC
will pack "long long" bitfields across 8-byte boundaries, and will pad
them only to 4-byte boundaries (e.g., a struct containing two fields
of type "long long : 4" will have size 32 bits, not 64 bits). That
seems needlessly inconsistent to me, but I don't know what other
compilers do. I'll find out what ours does on Monday. ;)

-Arthur,
one of those compiler folks
Feb 24 '07 #4
"Arthur J. O'Dwyer" <aj*******@andr ew.cmu.eduwrite s:
[...]
(C99 introduced anonymous bitfields to deal with the same issue.)
[...]

C90 has anonymous bitfields.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 24 '07 #5
On Feb 23, 11:43 pm, "Arthur J. O'Dwyer" <ajonos...@andr ew.cmu.edu>
wrote:
On Fri, 23 Feb 2007 mark...@yahoo.c om wrote:
Although the C90 standard only mentions the use of 'signed int' and
'unsigned int' for bit-fields (use 'int' at your own risk) and C99
adds _Bool.
It seems that most compilers create the size of the bit-field object
from the size used to specify the field.
Could this be considered a defacto standard now (at least for 8 bit
sized bit-fields)?

I don't exactly see what you mean. I think you are saying that on
"most" compilers, the structure definition
struct {
unsigned char x:4;
unsigned char y:4;
} nibs;

yields a struct with a size of 8 bits, arranged as xxxxyyyy, but
struct {
unsigned int x:4;
unsigned int y:4;
} nibs;

yields a struct with a size of 32 bits, arranged as
xxxxyyyy0000000 000000000000000 00.

This is indeed true for Keil's compiler:
http://www.keil.com/support/docs/928.htm

and GCC and yes, probably most modern compilers. However, there's
an extra wrinkle that you didn't mention: On "most" compilers, a
bitfield of declared type T will never span memory chunks of
size T. (The real type of a bitfield is simply a "bit-field type"; but
like you, I'm talking about the "unsigned char" or whatever that you
use in the struct definition.)
For example, an "unsigned char" bitfield will never span two bytes;
padding bits will be inserted if necessary to justify it in its own
byte.
bitfield of declared type T - I originally thought that bitfields
were of bit-field-type, that K&R could have created a new reserved/key
word for, such as 'bitf', if desired.

not real code:
struct {
unsigned bitf x : 5;
unsigned bitf y : 5;
signed bitf z : 6;
} nabs;

But it seems now that type has more meaning.

Therefore, the struct definition
>
struct {
unsigned char x : 5;
unsigned char y : 5;
} nabs;

will correspond on "most" compilers to xxxxx000yyyyy00 0, while

struct {
unsigned short x : 5;
unsigned short y : 5;
} nabs;

will correspond to xxxxxyyyyy00000 0.
If you care about that kind of micro-optimization,
you probably welcome the extra tiny bit of control over alignment given
to you by the "de-facto" standard.
The issue may originally have been that unaligned memory accesses are
terribly slow on most platforms; therefore, it makes sense to allow the
programmer to force byte-alignment or word-alignment with a minimum of
fuss. (C99 introduced anonymous bitfields to deal with the same issue.)
The issue now is certainly compatibility with other compilers. Peer
pressure is a strong force in the compiler field.
When you interface with hardware or send packed data between CPUs
the bits have to be exact which is probably the primary motivation
here.
>
N869 section 6.7.2.1#9 seems to encourage the "de-facto" behavior:

[#9] An implementation may allocate any addressable storage
unit large enough to hold a bit-field. 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. If insufficient space remains, whether a
bit-field that does not fit is put into the next unit or
overlaps adjacent units is implementation-defined. The
order of allocation of bit-fields within a unit (high-order
to low-order or low-order to high-order) is implementation-
defined. The alignment of the addressable storage unit is
unspecified.
Obviously programmers want to use bit-field objects that may be
smaller or larger than standard integer size shouldn't the standard
support that.

No. If there's no Standard support for 128-bit integer math, it
seems pretty silly to require implementations to support integer
math on bitfields of type "signed int foo : 128". That would put a
huge burden on implementors to deal with arbitrarily-wide integer
math, while making users jump through silly hoops to get at it.
I stand corrected the standard shouldn't force the use of these bit-
field types but maybe have an optional supplement/section that would
encourage compilers to extend in the same manner.

Feb 24 '07 #6

"Arthur J. O'Dwyer" <aj*******@andr ew.cmu.eduwrote
No. If there's no Standard support for 128-bit integer math, it
seems pretty silly to require implementations to support integer
math on bitfields of type "signed int foo : 128". That would put a
huge burden on implementors to deal with arbitrarily-wide integer
math, while making users jump through silly hoops to get at it.
Not a huge burden. It's another job which someone writing a quick and
cheerful compiler could probably do without, but no harder than implenting
floating -point arithmetic on machines without hardware float registers, for
instance.

Feb 24 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
2091
by: Sims | last post by:
Hi, I have some small questions that have never been any problems, (for my compiler?), but always make me curious. So here goes... what does the standard sday about the 'if' statement? for example if i have,
88
6022
by: Matt | last post by:
Hi folks. Can you help with some questions? I gather that some types supported by g++ are nonstandard but have been proposed as standards. Are the long long and unsigned long long types still under consideration for the ANSI C and C++ standards? Are they likely to be accepted into the standards? Which compilers support those types, and which do not?
28
2509
by: Timothy Madden | last post by:
Hello I've read here that only C language has a standard 64bit integer. Can you please tell me what are the reasons for this ? What is special about C language ? Can you please show me some references to this integer type ? When was it introduced ? Thank you
40
2069
by: Matt | last post by:
I want to know what is the latest C standard version? Is it C99? There are many terms I have heard, including C98, C99, C9X. Or should we call ANSI/ISO C? Please advise. Thanks!!
85
4866
by: fermineutron | last post by:
Some compilers support __asm{ } statement which allows integration of C and raw assembly code. A while back I asked a question about such syntax and was told that __asm is not a part of a C standard. My question now is: Is there a chance that such statement will become a part of C standard in the future? In some cases using asm language is the best way to acomplish some small task, hence integration of C and asm would greatly enhence C,...
270
9533
by: jacob navia | last post by:
In my "Happy Christmas" message, I proposed a function to read a file into a RAM buffer and return that buffer or NULL if the file doesn't exist or some other error is found. It is interesting to see that the answers to that message prove that programming exclusively in standard C is completely impossible even for a small and ridiculously simple program like the one I proposed. 1 I read the file contents in binary mode, what should...
130
6815
by: euler70 | last post by:
char and unsigned char have specific purposes: char is useful for representing characters of the basic execution character set and unsigned char is useful for representing the values of individual bytes. The remainder of the standard integer types are general purpose. Their only requirement is to satisfy a minimum range of values, and also int "has the natural size suggested by the architecture of the execution environment". What are the...
1
1827
by: Peter Michaux | last post by:
Hi, Is there a de facto standard C unit testing framework that is generally liked? Thank you, Peter
19
1180
by: W Karas | last post by:
1) Support the idiom: p - static_cast<C::*M>(p) C is a class. M is a data member of C (not a type). The value of p must implicitly convert to the type of M. If the value of p (after conversion) is the address of
6
1786
by: Chris Peters | last post by:
Hello I am debugging some code with gdb and want to watch a 64-bit long int value x. But gdb can only set 32-bit width watches. My solution is to watch these two things *((int *) &x) *((int *) &x + 1) But I understood from this group that this kind of "type punning" or
0
9591
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9425
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10225
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10053
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8880
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5312
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5449
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3573
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2816
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.