I've noticed that many C/C++ programmers implement sets of flags using something like the following:
#define FLAG_1 (1 << 0)
#define FLAG_2 (1 << 1)
#define FLAG_3 (1 << 2)
unsigned int my_flags = 0; /* no flag set */
my_flags |= FLAG_2; /* set flag 2 */
But is this approach actually sound? It seems to me like it's making assumptions about the binary representation of unsigned ints that isn't part of the C/C++ language standard. For example, that "0" is actually 0x0000.
Am I wrong? Or am I right in theory, but not in practice given currently standard hardware?
In programming languages like C or C++, Bit Flags are used to store more than one boolean value in one byte or a whole set of bytes. Usually, they are represented as binary.
For handling electronics and IoT-related operations, programmers use bitwise operators. It can operate faster at a bit level. The Bitwise Operator in C performs its operation on the individual bits of its operand, where operands are values or expressions on which an operator operates.
Flag variable is used as a signal in programming to let the program know that a certain condition has met. It usually acts as a boolean variable indicating a condition to be either true or false.
This set of states only requires one bit to store. However, if a variable must be at least a byte, and a byte is 8 bits, that means a Boolean is using 1 bit and leaving the other 7 unused.
The important part of the C++11 standard is §3.9.1/7 (ISO/IEC 14882:2011(E)):
The representations of integral types shall define values by use of a pure binary numeration system.
This is clarified in a footnote:
49) A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.)
The results of shift operators are defined mathematically. For example, for E1 << E2
:
If E1 has an unsigned type, the value of the result is E1 × 2E2 , reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.
The bitwise operators are specifically defined as being bitwise. For example, for bitwise OR:
The usual arithmetic conversions are performed; the result is the bitwise exclusive OR function of the operands.
Of course, under the as-if rule, the representation does not truly have to be the pure binary numeration system. The compiler must only produce a program that acts as if it were.
In C99 (ISO/IEC 9899:TC3), pure binary notation is only guaranteed for bit-fields and objects of type unsigned char
(§6.2.6.1/3):
Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.
Again clarified in a footnote:
A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral powers of 2, except perhaps the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.)
The standard specifically points out that bitwise operations depend on the internal representation (§6.5/4):
Some operators (the unary operator ~, and the binary operators <<, >>, &, ^, and |, collectively described as bitwise operators) are required to have operands that have integer type. These operators yield values that depend on the internal representations of integers, and have implementation-defined and undefined aspects for signed types.
While it's theoretically possible to run C or C++ on an architecture that uses non-power-of-2 arithmetic, the |
, &
, and ^
operators are defined to have bitwise behavior, so such a machine would need to emulate binary arithmetic.
It's therefore completely safe and portable.
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