C Language

Boolean

Remarks#

To use the predefined type _Bool and the header <stdbool.h>, you must be using the C99/C11 versions of C.

To avoid compiler warnings and possibly errors, you should only use the typedef/define example if you’re using C89 and previous versions of the language.

Using stdbool.h

Using the system header file stdbool.h allows you to use bool as a Boolean data type. true evaluates to 1 and false evaluates to 0.

#include <stdio.h>
#include <stdbool.h>

int main(void) {
    bool x = true;  /* equivalent to bool x = 1; */
    bool y = false; /* equivalent to bool y = 0; */
    if (x)  /* Functionally equivalent to if (x != 0) or if (x != false) */
    {
        puts("This will print!");
    }
    if (!y) /* Functionally equivalent to if (y == 0) or if (y == false) */
    {
        puts("This will also print!");
    }
}

bool is just a nice spelling for the data type _Bool. It has special rules when numbers or pointers are converted to it.

Using #define

C of all versions, will effectively treat any integer value other than 0 as true for comparison operators and the integer value 0 as false. If you don’t have _Bool or bool as of C99 available, you could simulate a Boolean data type in C using #define macros, and you might still find such things in legacy code.

#include <stdio.h>

#define bool int
#define true 1
#define false 0

int main(void) {
    bool x = true;  /* Equivalent to int x = 1; */
    bool y = false; /* Equivalent to int y = 0; */
    if (x) /* Functionally equivalent to if (x != 0) or if (x != false) */
    {
        puts("This will print!");
    }
    if (!y) /* Functionally equivalent to if (y == 0) or if (y == false) */
    {
        puts("This will also print!");
    }
}

Don’t introduce this in new code since the definition of these macros might clash with modern uses of <stdbool.h>.

Using the Intrinsic (built-in) Type _Bool

Added in the C standard version C99, _Bool is also a native C data type. It is capable of holding the values 0 (for false) and 1 (for true).

#include <stdio.h>

int main(void) {
    _Bool x = 1; 
    _Bool y = 0;
    if(x) /* Equivalent to if (x == 1) */
    {
        puts("This will print!");
    }
    if (!y) /* Equivalent to if (y == 0) */
    {
        puts("This will also print!");
    }
}

_Bool is an integer type but has special rules for conversions from other types. The result is analogous to the usage of other types in if expressions. In the following

_Bool z = X;
  • If X has an arithmetic type (is any kind of number), z becomes 0 if X == 0. Otherwise z becomes 1.
  • If X has a pointer type, z becomes 0 if X is a null pointer and 1 otherwise.

To use nicer spellings bool, false and true you need to use <stdbool.h>.

Integers and pointers in Boolean expressions.

All integers or pointers can be used in an expression that is interpreted as “truth value”.

int main(int argc, char* argv[]) {
  if (argc % 4) {
    puts("arguments number is not divisible by 4");
  } else {
    puts("argument number is divisible by 4");
  }
...

The expression argc % 4 is evaluated and leads to one of the values 0, 1, 2 or 3. The first, 0 is the only value that is “false” and brings execution into the else part. All other values are “true” and go into the if part.

double* A = malloc(n*sizeof *A);
if (!A) {
   perror("allocation problems");
   exit(EXIT_FAILURE);
}

Here the pointer A is evaluated and if it is a null pointer, an error is detected and the program exits.

Many people prefer to write something as A == NULL, instead, but if you have such pointer comparisons as part of other complicated expressions, things become quickly difficult to read.

char const* s = ....;   /* some pointer that we receive */
if (s != NULL && s[0] != '\0' && isalpha(s[0])) {
   printf("this starts well, %c is alphabetic\n", s[0]);
}

For this to check, you’d have to scan a complicated code in the expression and be sure about operator preference.

char const* s = ....;   /* some pointer that we receive */
if (s && s[0] && isalpha(s[0])) {
   printf("this starts well, %c is alphabetic\n", s[0]);
}

is relatively easy to capture: if the pointer is valid we check if the first character is non-zero and then check if it is a letter.

Defining a bool type using typedef

Considering that most debuggers are not aware of #define macros, but can check enum constants, it may be desirable to do something like this:

#if __STDC_VERSION__ < 199900L
typedef enum { false, true } bool;
/* Modern C code might expect these to be macros. */
# ifndef bool
#  define bool bool
# endif
# ifndef true
#  define true true
# endif
# ifndef false
#  define false false
# endif
#else
# include <stdbool.h>
#endif

/* Somewhere later in the code ... */
bool b = true;

This allows compilers for historic versions of C to function, but remains forward compatible if the code is compiled with a modern C compiler.

For more information on typedef, see https://stackoverflow.com/documentation/c/2681/typedef, for more on enum see https://stackoverflow.com/documentation/c/5460/enumerations


This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow