Given a struct S:
struct S {
bool a : 1;
bool b : 1;
};
How to determine that S::a
and S::b
are bit-fields at compile time?
I was trying to come up a macro like IsBitField(S, a)
but had hard time to apply SFINAE with offsetof()
or addressof()
(which are known to be invalid operations per bit-fields).
It depends on your platform (underlying HW architecture + designated compiler), but in general - yes, the compiler most likely needs to add bit-wise operations (which typically result in larger code section and/or slower runtime execution).
In C, we can specify size (in bits) of structure and union members. The idea is to use memory efficiently when we know that the value of a field or group of fields will never exceed a limit or is within a small range. For example, consider the following declaration of date without the use of bit fields.
Again, storage of bit fields in memory is done with a byte-by-byte, rather than bit-by-bit, transfer.
No, you can't. Bit field can only be used with integral type variables.
Bit Fields in C. In C, we can specify size (in bits) of structure and union members. The idea is to use memory efficiently when we know that the value of a field or group of fields will never exceed a limit or is withing a small range. For example, consider the following declaration of date without the use of bit fields.
In C99, the allowable data types for a bit field include qualified and unqualified _Bool, signed int, and unsigned int. The default integer type for a bit field is unsigned. End of C only. Beginning of C++ only. A bit field can be any integral type or enumeration type. End of C++ only. The maximum bit-field length is 64 bits.
You can declare a bit field inside a structure. data_type defines the type of data which can be integer, signed integer or unsigned integer. member_name defines the name of the bit-field member inside the structure. width is the number of bits required in the bit field.
Structures, Unions and Bit fields are some of the important aspects of C programming language. While structures are widely used, unions and bit fields are comparatively less used but that does not undermine their importance. In this tutorial we will explain the concept of Structures, Unions and Bit fields in C language using examples.
First, for a SFINAE solution, the ellipsis overload trick (with expression SFINAE) still works, we just need to find a construct that is ill-formed when applied to a bitfield while well-formed when applied on a normal member.
For example, you cannot form a pointer-to-member if the member is a bitfield.
So we could write:
template <typename T>
struct is_bit_field_t {
template <typename U>
static constexpr bool helper(...) {
return true;
}
template <typename U>
static constexpr bool helper(decltype(&U::a) arg) {
return false;
}
static constexpr bool value = helper<T>(nullptr);
};
This will test whether the public member a
of U
is of bitfield type. Explanation:
T::a
is a bitfield, then the expression decltype(&U::a)
would be ill-formed, which would then SFINAE out the second overload.Live demo: https://godbolt.org/z/TTn8YPKW3
With C++20, this could be done with concepts, utilizing the fact that you cannot take the address of a bitfield.
The core implementation would just look like:
template <typename T>
concept A_IsBitField = !requires (T t) {
{ &t.a };
};
Live demo: https://godbolt.org/z/W3jbosY93
If you hate to define a standalone concept, you could just use the requires
expression instead (with the SFINAE method you have no choice but to create that struct)
Of course, the above only works for the member named a
. If you would like to use it with other members, then you need to rewrite the SFINAE trait or the concept, replacing a
with whatever member you want. You could write a macro to help you generate those constructs if you need a lot of them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With