473,406 Members | 2,273 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Bitfields in struct

Hello C Group,

From what I remember, it is implementation dependent the way that a
compiler may order bitfields in a struct. In the example program I give,
Solaris Sparc gives one result, Intel x86 gives another result (for the
GCC compiler).

Is there a portable way to test how this information is stored? In
particular, will the result of the program below always result in c
being 0x01 or 0x80? Does the compiler allow for padding so that the
result may also be 0x00?

For example:

#include <stdio.h>

struct bitfield {
int b7:1;
int b6:1;
int b5:1;
int b4:1;
int b3:1;
int b2:1;
int b1:1;
int b0:1;
};

union highlow {
struct bitfield bf;
unsigned char c;
};

int main(void)
{
union highlow h;

h.c = 0;
h.bf.b0 = 1;

if (h.c == 0x80) {
printf("LSB machine\n");
} else {
printf("MSB machine\n");
}
printf("c = %02x\n", h.c);
}

--
Jason.
Nov 15 '05 #1
2 8097
On Tue, 11 Oct 2005 13:21:00 +0200, Jason Curl
<j_********@motorola.com> wrote in comp.lang.c:
Hello C Group,

From what I remember, it is implementation dependent the way that a
compiler may order bitfields in a struct. In the example program I give,
Solaris Sparc gives one result, Intel x86 gives another result (for the
GCC compiler).

Is there a portable way to test how this information is stored? In
particular, will the result of the program below always result in c
being 0x01 or 0x80? Does the compiler allow for padding so that the
result may also be 0x00?
The result might be 0x01. It might even be 0x80, but that is rather
unlikely.
For example:

#include <stdio.h>

struct bitfield {
int b7:1;
Note that when used to define bit-field members, plain 'int' is not
necessarily signed int. It may be unsigned int, that is
implementation defined.

Also note that a one-bit signed bit-field is dicey. It can have two
values, but are they 0 and 1 or 0 and -1? Frankly the C standard
leaves this ambiguous, and the behavior of compilers varies.

For single bit bit-fields, it is safest to explicitly used unsigned
int, or, if you have a C99 conforming compiler, _Bool which is an
unsigned integer type.
int b6:1;
int b5:1;
int b4:1;
int b3:1;
int b2:1;
int b1:1;
int b0:1;
};
You seem to assume that this bit-field will occupy exactly 8 bits. No
such requirement or guarantee exists in the C standard. There are
some platforms that will use a whole int or larger type, 16 or 32 or
more bits, not just 8.
union highlow {
struct bitfield bf;
unsigned char c;
};

int main(void)
{
union highlow h;

h.c = 0;
h.bf.b0 = 1;

if (h.c == 0x80) {
printf("LSB machine\n");
} else {
printf("MSB machine\n");
}
printf("c = %02x\n", h.c);
}


Do you actually mean "LSb" and "MSb", that is least and most
significant bit?

Padding has nothing to do with it. Assume an implementation that will
use an int to store the bit-field struct, which is not at all unusual.
So the underlying int has, for example, 32 bits. It is
implementation-defined whether bit-fields are allocated starting with
the most significant or least significant bit, but assume a
little-endian architecture with CHAR_BIT 8 that starts allocating from
the most significant bit.

In that case, the representation of the bit-field interpreted as an
unsigned 32 bit int would be 0x80000000, and it would appear in
memory, from lowest to highest address as 0x00, 0x00, 0x00, 0x80.

Now suppose a bit-endian implementation that starts allocating
bit-fields from the least significant bit. In that case, the
representation of the unsigned bit-field interpreted as a 32-bit
unsigned int would be 0x00000001, and it would appear in memory as
0x00, 0x00, 0x00, 0x01.

You are assuming that because you define a bit-field struct containing
8 bits, and you overlay an unsigned char over its first byte (and you
assume that your char has exactly 8 bits), that all of the 8 bits in
the bit-field will lie within that 8-bit char. There is no guarantee
of that at all.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 15 '05 #2
Jack Klein wrote:
On Tue, 11 Oct 2005 13:21:00 +0200, Jason Curl
<j_********@motorola.com> wrote in comp.lang.c:
Is there a portable way to test how this information is stored? In
particular, will the result of the program below always result in c
being 0x01 or 0x80? Does the compiler allow for padding so that the
result may also be 0x00?
The result might be 0x01. It might even be 0x80, but that is rather
unlikely.
For example:

#include <stdio.h>

struct bitfield {
int b7:1;


Note that when used to define bit-field members, plain 'int' is not
necessarily signed int. It may be unsigned int, that is
implementation defined.

Also note that a one-bit signed bit-field is dicey. It can have two
values, but are they 0 and 1 or 0 and -1? Frankly the C standard
leaves this ambiguous, and the behavior of compilers varies.
int b6:1;
int b5:1;
int b4:1;
int b3:1;
int b2:1;
int b1:1;
int b0:1;
};


You seem to assume that this bit-field will occupy exactly 8 bits. No
such requirement or guarantee exists in the C standard. There are
some platforms that will use a whole int or larger type, 16 or 32 or
more bits, not just 8.
union highlow {
struct bitfield bf;
unsigned char c;
};

int main(void)
{
union highlow h;

h.c = 0;
h.bf.b0 = 1;

if (h.c == 0x80) {
printf("LSB machine\n");
} else {
printf("MSB machine\n");
}
printf("c = %02x\n", h.c);
}


Do you actually mean "LSb" and "MSb", that is least and most
significant bit?


Yes, LSb and MSb.
Padding has nothing to do with it. Assume an implementation that will
use an int to store the bit-field struct, which is not at all unusual.
So the underlying int has, for example, 32 bits. It is
implementation-defined whether bit-fields are allocated starting with
the most significant or least significant bit, but assume a
little-endian architecture with CHAR_BIT 8 that starts allocating from
the most significant bit.

In that case, the representation of the bit-field interpreted as an
unsigned 32 bit int would be 0x80000000, and it would appear in
memory, from lowest to highest address as 0x00, 0x00, 0x00, 0x80.

Now suppose a bit-endian implementation that starts allocating
bit-fields from the least significant bit. In that case, the
representation of the unsigned bit-field interpreted as a 32-bit
unsigned int would be 0x00000001, and it would appear in memory as
0x00, 0x00, 0x00, 0x01.
I'm assuming CHAR_BIT is 8, as required for POSIX. Must a conforming C
compiler must be consistent in how it allocates the bits?

For example, either 0x00000001, 0x80000000, 0x00008000 or 0x00000080 for
a 32-bit implementation. A 64-bit implementation would then possibly be
similar.

Or is this also in no way guaranteed by the C-standard? <ot> how about
these questions applied the posix standard? </ot>

You are assuming that because you define a bit-field struct containing
8 bits, and you overlay an unsigned char over its first byte (and you
assume that your char has exactly 8 bits), that all of the 8 bits in
the bit-field will lie within that 8-bit char. There is no guarantee
of that at all.


Rephrasing my question, does the C-standard specify (so that there are a
small number of limited possibilities) how two elements in a union overlay?

Thanks,
Jason.
Nov 15 '05 #3

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

Similar topics

3
by: Jon Slaughter | last post by:
I'm using bit fields to compactly represent some data I need to manage and I've read that they are not portable. I don't understand why that is the case? As long as I don't "indirectly" mess with...
0
by: tmartsum | last post by:
I have a discussion in comp.std.c++ After a (bit stupid) suggestion on representing a fixed 'big' length int I moderated it to "Bitfields-ints should be allowed to have any fixed length" I...
23
by: rohit | last post by:
Hi, In my couple of years of experience, I have never found a single instance where I needed to use unions and bitfields(though I have used structures).I was just imagining where would these find...
6
by: GalenTX | last post by:
I am looking for opinions on a possible approach to coping with bitfields in a heterogenous environment. We've got a bunch of legacy code which maps to hardware using bitfields. The code was...
19
by: Mehta Shailendrakumar | last post by:
Hi, I would like to know why array of bitfields is not possible. Is there any relation with processor architecture for this? Thank you for your time. Regards, Shailendra
3
by: TedKennedyMurderedHisPregnantMistress.dwpj65 | last post by:
Hello, I'm attempting to define a class that has a bitfield as a static member. The definition seems ok, but I'm at a loss as to how to declare it: class Test { static struct TestBitFields {...
7
by: sarathy | last post by:
Hi, 1. How it that the results for the size of struct1 and struct2 (below) are 4 and 3 # include <stdio.h> struct struct1 { const :16;
9
by: cman | last post by:
Who can explain to me what bitfields are and how to use them in practice? I would need a fairly detailed explaination, I would be a newbie to advanced C programming features. What are the...
10
by: lithiumcat | last post by:
Hi, This question seems to come up quite often, however I haven't managed to find an answer relevant to my case. I often use binary flags, and I have alaways used a "bitmask" technique, that...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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...
0
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,...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.