16

I'm writing a C++ application for Windows XP/Vista/7 using Visual Studio 2008. Some of my structures use a bit field, as shown in the example.

typedef struct myStruct_tag
{
    BYTE myVar1;
    WORD myVar2;
    WORD myVar3;
    union
    {
        struct
        {
            BYTE           :1;
            BYTE field1    :1;
            BYTE field2    :1;
            BYTE reserved  :5;
        } myBitField;
        BYTE myVar4;
    };
    BYTE myVar5;
    BYTE myVar6;
} myStruct_t;

Which end of the field is the most significant bit?

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
Jim Fell
  • 13,750
  • 36
  • 127
  • 202
  • 3
    Note: According to the standard, the MSB is not defined. On your specific platform, I suspect that `reserved` contains the MSB but I'm not positive. – Billy ONeal Dec 28 '10 at 16:24
  • @Billy: That looks like an answer to me. – Ben Voigt Dec 28 '10 at 16:26
  • Er... That's a rather strange question. You only have 3 bit fields in your declaration. 2 of them are 1-bit bit-fields, i.e. there's no issue of "which end" with them, since there's only 1 bit there. The only multi-bit bit-field called `reserved`, which suggests that it is not used at all. So, basically, the only bit-field you question can apply to is `reserved`. Are you asking about `reserved` specifically? If not, clarify your question. – AnT stands with Russia Dec 28 '10 at 16:26
  • @Ben: If I was positive w.r.t. which variable would get the MSB it would have been an answer, but I'm not positive... – Billy ONeal Dec 28 '10 at 16:27
  • This is important because the structure is used to define a packet for serial communications. The bit fields need to be aligned on both sides of the system, of which I unfortunately have control over only one side. – Jim Fell Dec 28 '10 at 16:30
  • @Billy: Do you have any suggestions as to where I can look for confirmation? A link would be helpful. – Jim Fell Dec 28 '10 at 16:38
  • @Jim: Err.. try on 1 side and see if it works; if not try on the other side lol. – Billy ONeal Dec 28 '10 at 17:02

3 Answers3

26

C99 standard 6.7.2.1/10 (emphasis mine):

An implementation may allocate any addressable storage unit large enough to hold a bitfield. 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.

So, the order must be documented by your compiler implementation.

However, so much about how bitfields are implemented are implementation defined or unspecified that using them to model hardware, wire-protocol, or file format bit fields in a portable fashion is not worth the trouble to attempt.

If you want your 'bit fields' to model something external to your program (like the above things), use explicit masks, setting and clearing the bits using the standard bit-wise operators (|, '&,~,<<`, etc.). Use helper inline functions (or even macros if you must) to make this easier/clearer in your code.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 2
    +10 if I could. Your answer to this question is the best reason not to use bitfields for the main thing people think they're useful for. – R.. GitHub STOP HELPING ICE Dec 28 '10 at 19:44
  • 1
    I didn't realise people try to use them portably, the only use I've seen is "talk to hardware from my program that uses compiler X". And look at all the zillions of "I do this in compiler X, how do I do that in compiler Y" questions. – Code Abominator Apr 14 '15 at 00:13
  • @CodeAbominator: as an example, I've seen bit fields used to crack network protocol messages or binary file formats. I have also seen some of that code fail to work when compiled for a different platform. – Michael Burr Apr 15 '15 at 07:14
  • This is exactly what bit fields are used for. It would be useful if a future C standard defined this behavior, but in the embedded world bitfields and unions are necessary and used by programmers and device manufactures in their header files. Be care, refer to the compiler documentation and don't expect it to be portable. Use in low level hardare dependent code, where its necessary to spicify particular bit and where use of masks would add to code size, reduce performance and give no benifit (as this type of code if by definition not portable). – user1582568 Nov 08 '20 at 18:51
8

The Visual Studio 2008 compiler docs indicate:

The ordering of data declared as bit fields is from low to high bit

From "C++ Bit Fields", MSDN C++ Language Reference, Visual Studio 2008 version

rakslice
  • 8,742
  • 4
  • 53
  • 57
  • As others have noted, the relevant standards do not specify this, and it's nice to write standards-compliant code, but this is the answer to the question that was asked, and the reader can decide whether they want to use their powers for good or for awesome. ;P – rakslice Feb 23 '17 at 08:08
2

If you're asking about which bits in myBitField are stored in which bits of the byte in memory, that's explicitly undefined by the C standards. You'll have to learn by experimentation. It's probably worthwhile, if you're doing something where this actually matters, to instead use an approach where you #define field1 as a hex value (for example, 0x40 or 0x02) and put it where you want it.

Jay Maynard K5ZC
  • 351
  • 2
  • 11
  • Unfortunately, functional testing of this portion of code is at least weeks, if not months away. (There's a lot that has to get written to really test any of it because I'm at a point now where everything left to write is more-or-less interdependent on everything else.) Defined constants are an option, but I would prefer to use bit fields because the former would require a *lot* more logic in my code. – Jim Fell Dec 28 '10 at 16:36
  • 2
    Well, a quick experiment should show you what the compiler's doing now...just define the union as above, assign 0 to `myVar4`, then assign 1 to `field1` and print the resulting value from `myVar4`. I'd hang a name on the unused bit you have defined before `field1`, though, lest the compiler optimize it away. – Jay Maynard K5ZC Dec 28 '10 at 16:58