Boolean Data Type in C

The C language considers any value different from zero as true. However, for many years, there was no proper boolean data type. In this article, we will look at how to represent boolean values in C89 and in C99 standards.

Boolean Values in C89

For years, the C language lacked a proper boolean type—that is, a data type capable of storing a true or false value.

We have seen that C treats as true anything that is different from zero, so one solution to this problem was to use variables of type int to store 0 (thus false) or 1 (thus true).

So, for example, a boolean variable—technically called a flag—could be represented in C like this:

int flag;

flag = 0; /* false */

/* ... */

flag = 1; /* true */

Although this technique works, it’s not the most readable solution. Also, it’s not immediately clear that the flag variable should only be assigned the values 0 and 1, and that these values represent false and true, respectively.

Therefore, in programs written for C89 compilers, programmers often tended to define simple macros with the names TRUE and FALSE:

#define TRUE 1
#define FALSE 0

So that assigning values to boolean variables became much more readable:

int flag;

flag = FALSE; /* false */

/* ... */

flag = TRUE; /* true */

Having done that, we can test the flag variable in an if statement:

if (flag == TRUE) {
    printf("The flag variable is true\n");
} else {
    printf("The flag variable is false\n");
}

Or, more concisely, we can write:

if (flag) {
    printf("The flag variable is true\n");
} else {
    printf("The flag variable is false\n");
}

This last form, in particular, is perhaps the most correct, since—as we’ve seen—C considers any value different from zero as true. As a result, even if by mistake we assign to the flag variable a value other than 0 or 1, the if statement will still work correctly.

Likewise, to test whether a boolean variable is false, we can write:

if (!flag) {
    printf("The flag variable is false\n");
} else {
    printf("The flag variable is true\n");
}

In this case, the ! (not) operator inverts the value of the flag variable: if flag is 0, then !flag is 1, and vice versa.

This idea of using int to represent boolean values was often taken a step further, where macros were defined to represent the boolean type as follows:

#define BOOL int

#define TRUE 1
#define FALSE 0

BOOL flag;

flag = FALSE; /* false */

/* ... */

flag = TRUE; /* true */

In this way, it was made even more explicit that the flag variable was a boolean type, even though it was actually just an int.

In upcoming lessons, we’ll see more refined techniques to define a boolean type in C, such as enumerations and custom type definitions.

Boolean Values in C99 and Beyond

The absence of a boolean type in C was definitively resolved in the C99 standard, which introduced a new data type called _Bool.

In the C99 standard, we can therefore declare a boolean variable like this:

_Bool flag;

Internally, a variable of type _Bool is nothing more than an integer, specifically an unsigned int. However, unlike a regular integer variable, it can only take the values 0 and 1. In general, if we try to assign a value other than 0 to a _Bool variable, the compiler will automatically assign it the value 1.

For example, we can write:

_Bool flag;

flag = 8; /* flag takes the value 1 */

Since, in practice, they are integers, it is possible to perform mathematical operations on variables of type _Bool. However, it is good practice to avoid doing so and to use these variables solely for evaluating conditions.

Furthermore, it is possible to print such variables using the %d format specifier:

printf("The value of flag is %d\n", flag);

In this case, the value of flag will be printed as 1.

Definition

_Bool Data Type

The _Bool data type is a data type introduced in the C99 standard to represent boolean values. The _Bool type can only take two values: 0 and 1, which represent false and true, respectively.

The name given to the _Bool data type may seem strange at first. Why not use a simpler name like bool? The answer is that, when the C99 standard was defined, it was necessary to maintain backward compatibility with old programs written for the previous standard. For this reason, since old programs defined types like bool and true using macros, a name was chosen that would not conflict with them.

Moreover, the C89 standard dictates that any name beginning with an underscore followed by an uppercase letter or another underscore is reserved for the compiler. Therefore, the name _Bool is a reserved name.

The C99 standard also introduced a new library, <stdbool.h>, which simplifies working with boolean values.

Specifically, it defines three macros:

  • bool, which is an alias for _Bool; although starting from the C23 standard it is no longer an alias but a true type;
  • true, which is an alias for 1;
  • false, which is an alias for 0.

So we can write:

#include <stdbool.h>

bool flag;

flag = true; /* true */

/* ... */

flag = false; /* false */

In this way, the code becomes more readable and closer to natural language.

Definition

<stdbool.h> Header

The <stdbool.h> header is a header introduced in the C99 standard that defines three macros to simplify working with boolean values:

  • bool, which is an alias for _Bool;
  • true, which is an alias for 1;
  • false, which is an alias for 0.

Summary

  • In C89, there is no boolean data type, so variables of type int are used to represent boolean values;
  • To make the code more readable, you can define macros TRUE and FALSE to represent the values 1 and 0, respectively;
  • In the C99 standard, the _Bool type was introduced to represent boolean values;
  • In the C99 standard, the <stdbool.h> library was introduced, which defines three macros to simplify working with boolean values: bool, true, and false.