I saw the below code in this Quora post:
#include <stdio.h>
struct mystruct { int enabled:1; };
int main()
{
struct mystruct s;
s.enabled = 1;
if(s.enabled == 1)
printf("Is enabled\n"); // --> we think this to be printed
else
printf("Is disabled !!\n");
}
In both C & C++, the output of the code is unexpected,
Is disabled !!
Though the "sign bit" related explanation is given in that post, I am unable to understand, how it is possible that we set something and then it doesn't reflect as it is.
Can someone give a more elaborate explanation?
Note: Both the tags c & c++ are required, because their standards slightly differ for describing the bit-fields. See answers for C specification and C++ specification.
As per the C++ standard n4713, a very similar code snippet is provided. The type used is BOOL
(custom), but it can apply to any type.
12.2.4
4 If the value true or false is stored into a bit-field of type
bool
of any size (including a one bit bit-field), the originalbool
value and the value of the bit-field shall compare equal. If the value of an enumerator is stored into a bit-field of the same enumeration type and the number of bits in the bit-field is large enough to hold all the values of that enumeration type (10.2), the original enumerator value and the value of the bit-field shall compare equal. [ Example:enum BOOL { FALSE=0, TRUE=1 }; struct A { BOOL b:1; }; A a; void f() { a.b = TRUE; if (a.b == TRUE) // yields true { /* ... */ } }
— end example ]
At 1st glance, the bold part appears open for interpretation. However, the correct intent becomes clear when the enum BOOL
is derived from the int
.
enum BOOL : int { FALSE=0, TRUE=1 }; // ***this line
struct mystruct { BOOL enabled:1; };
int main()
{
struct mystruct s;
s.enabled = TRUE;
if(s.enabled == TRUE)
printf("Is enabled\n"); // --> we think this to be printed
else
printf("Is disabled !!\n");
}
With above code it gives a warning without -Wall -pedantic
:
warning: ‘mystruct::enabled’ is too small to hold all values of ‘enum BOOL’
struct mystruct { BOOL enabled:1; };
The output is:
Is disabled !! (when using
enum BOOL : int
)
If enum BOOL : int
is made simple enum BOOL
, then the output is as the above standard pasage specifies:
Is enabled (when using
enum BOOL
)
Hence, it can be concluded, also as few other answers have, that int
type is not big enough to store value "1" in just a single bit bit-field.