Solved

Bit fields

Posted on 1998-05-14
15
194 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
 

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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
ASP.net build a IF/Then Walkthrough Guide 1 191
C++ question 3 62
Eclipse IDE - Cannot copy/paste from console output 8 132
Least Squares Curve Fitting 4 61
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

895 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now