How to insert booleans into a bitfield in C89
As far as I understand, in C89 all boolean expressions are of type integer. This also means that function parameters that represent bool usually get represented by an int
parameter.
Now my question is how I can most ideally take such an int
and put it into a bitfield so that it only occupies one bit (let's ignore padding for now).
The first thing here is which type to use. Using int
or any other unsigned type doesn't work, because when there is only one bit, only -1
and 0
can be represented (at least with two's complement).
While -1
technically evaluates as true
, this is not ideal because actually assigning it without undefined behavior can be quite tricky from what I understand.
So an unsigned type should be chosen for the bitfield:
typedef struct bitfield_with_boolean {
unsigned int boolean : 1;
} bitfield_with_boolean;
The next question is then how to assign that bitfield. Just taking an int
or similar won't work because the downcast truncates the value so if the lowest bit wasn't set, a value that would previously evaluate to true
would now suddenly evaluate to false
.
As far as I understand, the boolean operators are guaranteed to always return either 0
or 1
. So my idea to solve this problem would be something like this:
#define to_boolean(expression) (!!(expression))
So in order to assign the value I would do:
bitfield_with_boolean to_bitfield(int boolean) {
bitfield_with_boolean bitfield = {to_boolean(boolean)};
return bitfield;
}
Is that correct, and or is there a better way?
NOTE:
I know the problem is completely solved starting with C99 because casting to _Bool
is guaranteed to always result in either a 0
or a 1
. Where 0
is only the result if the input had a value of 0
.
Yes, your solution is correct. However, I wouldn't hide it behind a macro, and I wouldn't name a macro using all_lowercase
letters.
!!var
is sufficiently idiomatic that I'd say it's fine in code.
Alternatives include var != 0
and, of course, var ? 1 : 0
var ? 1 : 0
.
上一篇: 64应该是sizeof(int)
下一篇: 如何在C89中将布尔值插入到位域中