2

In ISO standard C, my understanding is that there is nothing that actually nails down the the representation of a _Bool, but it does say:

  • "_Bool is large enough to hold the values 0 and 1"
  • "When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1"
  • "number of bits in a _Bool is atleast CHAR_BIT the width of a _Bool can be just 1 bit"

I am thinking then (and from other related answers), that the representation of false need not actually be 0 (even though in nearly all implementations, it is). So what happens if you memset a _Bool to 0, then use it somehow? Is this undefined behavior (by default because it is not defined in the standard) or implementation defined behavior? This seems to matter (in my understanding) because in the former case, it's not a well defined C program, in the latter it is. For example is this undefined behavior? Can false have a representation other than 0?

#include <stdbool.h>

//...

bool x = true;

memset(&x, 0, sizeof(bool));

if(x == true)
{
    printf("Zero is true!");
}
else
{
    printf("zero is false!");
}

Lundin
  • 195,001
  • 40
  • 254
  • 396
Jesse
  • 51
  • 2
  • There are no true and false values in C (there are macros true and false in stdbool.h but you don't have to use them). _Bool is an unsigned integer type. As with any arithmetic types, there is a zero value, and there are non-zero values, and they behave like values of any other arithmetic type in conditional operators. – n. m. could be an AI Mar 18 '22 at 06:54
  • On your last bullet-point, see: [What is CHAR_BIT?](https://stackoverflow.com/q/3200954/10871073) – Adrian Mole Mar 18 '22 at 09:07
  • Related post with some fun examples of UB: [_Bool type and strict aliasing](https://stackoverflow.com/q/52163870/584518) – Lundin Mar 18 '22 at 09:26

1 Answers1

2

_Bool is an unsigned integer type. It can represent at least values 0 and 1. Note there are no separate true and false values. The macro true in stdbool.h expands to the constant 1, and the macro false to the constant 0 7.18. So x == true is the same as x == 1.

There are two kinds of bits in an unsigned integer type: value bits and padding bits 6.2.6.2p1. Your invocation of memset sets all bits (value and padding) to zero.

For any integer type, the object representation where all the bits are zero shall be a representation of the value zero in that type 6.2.6.2p5.

Thus, the program fragment as shown has no visible undefined, unspecified or implementation-defined behaviour. A reasonably completed program shall print zero is false.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243