C23 Native bool, true, and false Keywords

The C23 standard marks a major evolution in the C programming language by standardizing bool, true, and false as native language keywords. Prior to C23, developers relied on integer types, custom macros, or the <stdbool.h> header introduced in C99 to handle boolean logic. This article explains the historical context of boolean representations in C, how C23 integrates these keywords natively into the language core, and the practical implications for modern C software development.

The Evolution of Booleans in C

In the early revisions of C (such as C89 and C90), the language lacked a dedicated boolean type. Conditions evaluated integer values directly, treating 0 as false and any non-zero value as true. Developers routinely defined custom macros or enum types to emulate boolean logic, leading to inconsistencies across different codebases and libraries.

The C99 standard attempted to address this fragmentation by adding the primitive type keyword _Bool. Because existing code frequently defined identifiers named bool, true, and false, the committee chose not to make these direct keywords. Instead, C99 introduced the <stdbool.h> header, which contained macro definitions:

#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1

While functional, this approach required explicit inclusion of <stdbool.h> and resulted in true and false being integer literals (int) rather than boolean literals.

Native Standardization in C23

The C23 standard (ISO/IEC 9899:2024) officially elevated bool, true, and false to core language keywords.

Key changes introduced in C23 include:

  • Keyword Promotion: bool, true, and false are now reserved keywords in the C language grammar, eliminating the need to #include <stdbool.h> to use standard boolean syntax.
  • Proper Type Assignment: The keywords true and false are predefined constants of type bool, whereas under C99 macros they expanded to the integer values 1 and 0.
  • Preservation of _Bool: The _Bool keyword remains as an alternative spelling for backward compatibility, but standard implementations define bool and _Bool as the same underlying type.
  • The Role of <stdbool.h>: The header <stdbool.h> is retained for legacy compatibility. In C23, it is effectively an empty header or provides standard macro indicators such as __bool_true_false_are_defined, allowing legacy code to compile without modification.

Practical Implications for Developers

Standardizing native boolean keywords improves code readability and cross-language compatibility, particularly with C++. In mixed C and C++ environments, headers declaring boolean interfaces no longer suffer from macro collisions or discrepancies between integer-based macro evaluations and genuine boolean types.

Additionally, static analysis tools, compilers, and debuggers can now enforce stricter type safety. Expressions involving boolean logic yield consistent boolean types across all translation units, reducing subtle bugs introduced by custom macro redefinitions or accidental integer manipulations.