Jump to content
  • Advertisement
Sign in to follow this  
MARS_999

int xa : 2; huh?

This topic is 2231 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have never seen this syntax before so I am curious to what it means or accomplishes?

Thanks!

BTW I couldn't find it on the net...

Share this post


Link to post
Share on other sites
Advertisement
The struct bitfield marker is a leftover part of C. There are almost no good reasons to use them any more.

Back in the old days, in the 70's and 80's when bitfields were good, memory was very expensive. There was no on-die cache until the mid to late '80s so anything that touched memory was slow. There was no CPU pipeline, so if you could use multiple instructions that avoided a trip to memory you could see great performance improvements. Using a bitfield, or in other words, having the compiler perform bit shifts followed by the compares or other operations you need followed by another bitshift back, was much faster than using a single byte of memory.

Today this is the opposite case. Memory is cheap and plentiful. On-die cache can contain more than the largest HDDs of that earlier era; there is practically no benefit to the space usage, and the compressed space may even result in cache alignment penalties. With deep pipelines, the shift operations are expensive and will stall your CPU. Using a bitfield in modern code is a huge performance penalty, and should only be used when you have specific reasons to take that penalty.

Share this post


Link to post
Share on other sites

Clang uses bitfields a lot in its data structures to conserve memory.

Clang is also a C/C++ compiler, and hence its memory usage can explode exponentially on the most trivial of files. It also spends most of its time doing string parsing, and as such the extra overhead of the bit shifting operations is negligible compared to the cost of the string operations.

Share this post


Link to post
Share on other sites
It can be useful when dealing with existing binary file formats or potentially when sending data over network.

It's also used sometimes on embedded systems where ram etc is very small. I once had a lab assignment in my introduction to embedded systems class where we were required to use bit fields for something (turning leds on/off by flipping bits or something like that). Turned out that particular version of GCC on that particular platform generated faulty code when dealing with bit fields so we had to resort to manual shifting/masking/xoring and what-not. Edited by DvDmanDT

Share this post


Link to post
Share on other sites

The struct bitfield marker is a leftover part of C. There are almost no good reasons to use them any more.

Back in the old days, in the 70's and 80's when bitfields were good, memory was very expensive. There was no on-die cache until the mid to late '80s so anything that touched memory was slow. There was no CPU pipeline, so if you could use multiple instructions that avoided a trip to memory you could see great performance improvements. Using a bitfield, or in other words, having the compiler perform bit shifts followed by the compares or other operations you need followed by another bitshift back, was much faster than using a single byte of memory.

Today this is the opposite case. Memory is cheap and plentiful. On-die cache can contain more than the largest HDDs of that earlier era; there is practically no benefit to the space usage, and the compressed space may even result in cache alignment penalties. With deep pipelines, the shift operations are expensive and will stall your CPU. Using a bitfield in modern code is a huge performance penalty, and should only be used when you have specific reasons to take that penalty.

There still are reasons to use this technique and they will never disappear as long as we have console games. Consoles have a far more restricted memory model then a general PC and they are using modern CPU's.

You also benefit from bit fields when they are embedded in an object where the game or application spawns more than a few thousand of these objects. Compare the size of an object that contains 8 bools with one that contains one unsigned int as a bit field, you have a memory saving of 7*4 bytes per object you create.

There are also ways to break alignment without using bit fields btw

struct
{
short x;
int y; //Not on a 4 byte alignment here.
}


There are a lot of valid ways you can use bit fields you just have to be mindful of what you are doing when you do use them. Edited by NightCreature83

Share this post


Link to post
Share on other sites
C was invented in the 1960s to help improve the productivity of the folks writing and maintaining the Unix operating system.

An operating system is a piece of software that sits directly on top of the hardware, converting the various electrical signals into abstract concepts that can be manipulated mathematically to emulate some other phenomena in the minds of observers. Many of those electrical signals are binary in nature (due to the design of binary digital computers) and routed through a collection of wires known as "address lines" and "data lines". These wires are arranged logically so that when a certain pattern of high and low voltages appear on them, other hardware performs some action.

From a logical point of view, arranging an appropriate combination of high and low voltages on the address lines and data lines is seen as "writing a data word to a register" or "reading a data word from a register". The hardware control and status wires were logically seen to be bundled into word-size chunks and "mapped" into memory. Thus, controlling hardware was seen from the point of view of an OS developer as reading and writing words to and from memory, since most CPUs only performed word-oriented memory operations. The hardware, however, generally dealt with bit-oriented data at the control level. For example ready-to-send and ring-detected are binary states.

So, the OS developer sees hardware as a bunch of words in memory, each word containing several bit-oriented fields. Now, he could spend a lot of time writing code to perform bit shifting and masking, but the end result is a lot of duplicated code (as much as 80% of the code) that is hard to read and has a high maintenance overhead. Or, if a new language is being developed to reduce the cost of maintenance overhead, bit field manipulations could be built in and the developers could spend more time drinking coffee and stroking their neck beards.

So, historically, bitfields in C were developed to make low-level OS development easier, faster, and cheaper (as was the entire language). Interestingly enough, OS development continues to this day with new hardware introduced daily and reams of code written taking advantage of the bitfield facility. This feature of the (almost half-a-century-old) language is still widely used and very useful, and definitely one of the reasons for its longevity.

If you're writing application-level code you are unlikely to need to use that language feature, unless you're developing a loader for older binary-format data files (and chances are, there's already a loader available for them, 'cos they're older). It certainly does not hurt to know what bitfields are and how they work, you never know when you'll need to patch your OS kernel.

Share this post


Link to post
Share on other sites

There are also ways to break alignment without using bit fields btw

struct
{
short x;
int y; //Not on a 4 byte alignment here.
}


Uh, no. If the integral type requires a 4 byte alignment then the structure will be padded to ensure a 4 byte alignment, which usually means it will end up actually looking something like:
struct
{
short x;
short __unused__; // padded to ensure proper alignment of the following int.
int y;
};

The only time the piece of code you posted might not be properly aligned in such a manner was if your compilers packing for the file was altered, typically through explicit control in the source files (for instance in visual studio you can use #pragma pack), or through compiler flags. Edited by Washu

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!