Solved

Bit fields

Posted on 1998-05-14
15
196 Views
Last Modified: 2010-04-10
I have created a structure which looks like the following:
struct my_struct {
   unsigned short my_short : 8;
   int            my_int;
};
I would expect the size of this structure to be 5 bytes, yet when I compile and run this I get 6 bytes.  I have used the pragma pack(1) and the /Zp1 project settings and get the same results.  This program is running on a WinNT computer.  Is there any way to get the structure to be 5 bytes instead of 6?  Why does the bit field not seem to work?
0
Comment
Question by:jerm
  • 6
  • 6
  • 2
  • +1
15 Comments
 
LVL 22

Accepted Solution

by:
nietod earned 50 total points
ID: 1177328
answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177329
shorts are two bytes so

short my_short:8;

says allcoate rome for two bytes, but use only 8 bits of it.
char are one byte so use char instead of short and you should be fine.

struct my_struct {
       unsigned char my_short : 8;
       int            my_int;
    };
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1177330
nietod is correct.  I tried that suggestion and the size of the structure was 5 bytes.  It did not matter if the char was the first element or the second.  It also did not mattter if char was signed or unsigned.  Thanks
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:jerm
ID: 1177331
Roger, you would be right, if it weren't for the fact that the structure was packed.  He said in the question he used

#pragma pack(1)

which prevents alignment.  Both the character type field AND the no-packing option are needed.  Since he had one, I just mentioned the other.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177332
Aha .. just found the reason...

>>>>>>>>>>
Microsoft Specific ®

Bit fields defined as int are treated as signed. A Microsoft extension to the ANSI C standard allows char and long types (both signed and unsigned) for bit fields. Unnamed bit fields with base type long, short, or char (signed or unsigned) force alignment to a boundary appropriate to the base type.
>>>>>>>>>>

Although this is ONLY mentioned in the C language bitfield info, and not the C++ section.

In C++ you can ues any integral type for a bitfield type, but there is no mention of this C extension in this case.

The explanation given by nietod is sort-of-correct (mine was not at all :-()

The results one gets are interesting...

struct S {
  long x:1;
  long y:1;
  long z:1;
}
sizeof (S) = 4 (1 long with 3 1-bit fields used)

struct S {
  long x:1;
  char y:1;
  long z:1;
}
sizeof (S) = 9 (1 long with 1 bit used, 1 char with 1 bit and another long with 1 bit)

It appears VC groups sucessive bitfields of the same type together and takes the all those bit field out of a single object of that type (eg. above, 3 1-bit field from a long). Whenever a new type for a bitfield is found, then this starts again.

This appears to be weird behaviour.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1177333
nietod .. with your explanation

struct S {
  long x:1;
  long y:1;
  long z:1;
}
would give a size of 12 (3 longs with 1-bit used of each.

but when actually trying it (yes.. I tried it after seeing that my reading of the docs didn't match the reported experimental evidence)

sizeof (S) = 4 (1 long with 3 1-bit fields used)

and this is with packing of 1.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1177334
Actually, I would have expected

struct S {
        long x:1;
        long y:1;
        long z:1;
      }
to be 4, which is right.  Add I would have expected

struct S {
        long x:1;
        char y:1;
        long z:1;
      }

to be... well ... a positive number, which is also right!  I checked in the Stroustrup book and there is no clear explantion of how this is supposed to work.  I guess it is implimentation defined.  however the VC docs seem to suggest that allowing char or short types is a Microsoft extension.  That is not true, according to Stroustrup it can be any integer type or bool.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177335
It can be any (integral) type (that is standard) .. but what the MS extension is, is how that integral type is interpreted .. (ie the effect that it has on alignment/padding).

The nasty thing about that is that if you set up

struct X {
  bool b : 1;
};

in an attempt to get as small a bool type as possible, under VC you'll still get the same size as

struct Y {
  bool b;
};

bitfields only seem to make a difference when you have several of the same type consecutively, otherwise the storage requirements are the same as for the base type.

I don't think that is very nice :-(

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1177336
I must say that I have enjoyed and learned a lot from the comments to my question.  I appreciate you help.  I wound up using a combination of your suggestions in my project.  Furthermore, I do not like the way bit fields seem to work.  All of the documentation I have read seems to indicate that bit fields should affect the size of the struct element, therefore the size of the struct.  Unfortunately it only affects the portion of the element which may be used.  Not sure if this is a MS thing, since I got the same results with gcc.  Have a nice day.
0
 

Author Comment

by:jerm
ID: 1177337
You said,

>> All of the documentation I have read seems to indicate that bit
>>  fields should affect the size of the struct element, therefore the
>>  size of the struct

You do know that this in byte increments, don't you? (or as we see here in multipliles of byte increments)  You should not expect

struct
{
   long x:1;
}

to create a structure that is one bit long.  The size of a structure is going to be in whole bytes so the debate was whethor that should be 1 byte or 4 bytes, not 1 bit.  Does that make sense?

If it does make sense, you should accept the answer.  If not, I'll try to explain.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177338
Technically (nit picking here) the size is in multiples of the size of a char - in most/many systems (PC certainly), this is one 8-bit byte.

This discussion has been enlightening and surprising for me.  Bit fields in VC certainly behave differently than I would have thought also.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1177339
Bang!  The autograder hits again!
0
 
LVL 11

Expert Comment

by:alexo
ID: 1177340
??? Do you post that on all auto grades now?  
0
 
LVL 22

Expert Comment

by:nietod
ID: 1177341
Acutally .. I think that EE should post a comment saying that the question has been auto-graded.

At least the right person got the points for this one.
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 1177342
>> Do you post that on all auto grades now?
Whenever I get an email notification, check out the question and find out it's an autograder false alarm, then, yes, I voice my complaint.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Exception thrown at 0x00007FFD5BC81F28 7 49
Issues with C++ Class 19 101
One named event, multiple event handlers 2 24
Gaming Software 1 19
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

861 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question