The Current C Programming Language Standard – ISO/IEC 9899:2024 (C24)

The current standard for the programming language C is ISO/IEC 9899:2024 – Information technology – Programming languages – C.
What Is C?
Today, C is one of the most popular programming languages used worldwide for operating systems, network drivers, databases, language interpreters, and utilities, as well as a variety of other purposes.
While it originated in the 70s, the existing practices of C were unified and expanded upon in the standard ANSI X3.159-1989, or C89. Because of these origins, many people still call the C programming language standard ANSI C. However, the C standard was adopted internationally in 1990, and it has long been ISO/IEC 9899, which is developed by ISO/IEC JTC 1. The integration of C practices into an international standard sparked its association with the name ISO C.
What Is ISO/IEC 9899?
ISO/IEC 9899:2024 specifies the form and establishes the interpretation of programs written in the C programming language. As stated in its scope, it specifies:
- The representation of C in programs
- The syntax and constraints of the C language
- The semantic rules for interpreting C programs
- The representation of input data to be processed by C programs
- The representation of output data processed by C programs
- The restrictions and limits imposed by a conforming implementation of C
Please note, however, that ISO/IEC 9899:2024 does not specify the mechanisms by which C programs are transformed for use by a data-processing system, C programs are invoked for use by a data-processing system, input data are transformed for use by a C program, or output data are transformed after being produced by a C program. The standard also doesn’t address the size or complexity of a program and its data that will exceed the capacity of any specific data-processing system, nor does it cover all minimal requirements of a data-processing system that is capable of supporting a conforming implementation.
ISO/IEC 9899:2024 Structure
The ISO/IEC 9899:2024 document is divided into four major subdivisions:
- preliminary elements (found in Clauses 1-4)
- the characteristics of environments that translate and execute C programs (Clause 5)
- the language syntax, constraints, and semantics (Clause 6)
- the library facilities (Clause 7)
Users should note that, since ISO/IEC 9899 undergoes periodic revision, new features could be added to or withdrawn from the document. Therefore, certain uses could conflict with future editions.
Changes to ISO/IEC 9899:2024
ISO/IEC 9899:2024, or C24, is a revision of ISO/IEC 9899:2021, or C18. Numerous changes were made to this international standard, including:
- New keywords were added, such as bool, static_assert, true, false, thread_local, and others, and implementations were allowed to provide macros for the older spelling with a leading underscore followed by a capital letter as well as defining old and new keywords as macros to enable transition of programs easily
- Integer width constraints and obsolete sign representations (so-called “1’s complement” and “sign-magnitude”) were removed
- One-argument version of static_assert was added
- Support was removed for function definitions with identifier lists
- Mandated function declarations whose parameter list is empty are now treated the same as a parameter list which only contain a single void
- The standard was harmonized with ISO/IEC 9945 (POSIX) through extended month name formats for strftime and integration of functions: gmtime_r, localtime_r, memccpy, strdup, strndup
- The standard was harmonized with floating-point standard ISO/IEC 60559, including integration of binary floating-point technical specification ISO/IEC TS 18661-1:2014, decimal floating-point technical specification ISO/IEC TS 18661-2:2015, floating-point types technical specification ISO/IEC TS 18661-3:2015, mathematical functions technical specification ISO/IEC TS 18661-4:2015, and new maximum and minimum functions for operations recommended in ISO/IEC 60559:2020
- The DECIMAL_DIG macro was made obsolescent
- Version test macros were added to library headers that contained changes to aid in upgrading and portability to be used alongside the __STDC_VERSION__ macro
- Placement of labels was allowed in front of declarations and at the end of compound statement
- The attributes feature was added, which includes the attributes:
- deprecated, for marking entities as discouraged for future use
- fallthrough, for explicitly marking cases where falling through in switches or labels is intended rather than accidental
- maybe_unused, for marking entities which can end up not being used
- nodiscard, for marking entities which, when used, should have their value handled in some way by a program
- noreturn, for indicating a function shall never return
- reproducible, for marking function types for which inputs always produce predictable output if given the same input (e.g. cached data) but for which the order of such calls still matter
- unsequenced, for marking function types which always produce predictable output and have no dependencies upon other data (and other relevant caveats)
- The u8 character prefix was added to match the u8 string prefix
- All u8, u, and U strings were mandated to be UTF-8, UTF-16, and UTF-32, respectively, as defined by ISO/IEC 10646
- Separated the literal, wide literal, and UTF-8 literal, UTF-16 literal, and UTF-32 literal encodings for strings and characters and now have a solely execution-based version of these, particularly execution and wide execution encodings
- mbrtoc8 and c8rtomb functions missing <uchar.h> were added
- Compound literals now may also include storage-class specifiers as part of the type to change the lifetime of the compound literal (and possibly turn it into a constant expression)
- The constexpr specifier for object definitions was added, and the standard improved what is recognized as a constant expression in conjunction with the constexpr storage-class specifier
- Support was added for initialization of objects with empty braces
- The typeof and typeof_unqual operations were added for deducing the type of an expression
- Tag compatibility rules were improved, enabling more types to be compatible with other types
- Bit-precise integer types _BitInt( N) and unsigned _BitInt( N) were added, where N can be an integer constant expression whose value is from one to BITINT_MAXWIDTH, inclusive
- Rules were improved for handling enumerations without underlying types, in particular allowing for enumerations without fixed underlying type to have value representations that have a greater range than int
- A new colon-delimited type specifier was added for enumerations to specify a fixed underlying type (and which, subject to an implementation’s definitions governing such constructs, adopt the fixed underlying type’s rules for padding, alignment, and sizing within structures and unions as well as with bit-fields)
- A new header and a suite of bit and byte-handling utilities were added for portable access to many implementations’ most efficient functionality
- Existing functions were modified to preserve the const-ness of the type placed into the function
- A feature was added to embed binary data as faithfully as possible with a new preprocessor directive #embed
- A nullptr constant and a nullptr_t type with a well-defined underlying representation identical to a pointer to void were added
- The VA_OPT specifier was added and language was clarified in the handling of macro invocation and arguments
- Support was mandated for variably modified types (but not variable length arrays themselves)
This list only includes roughly half of the extensive changes made to this standard. Users can find the change history of ISO/IEC 9899 in Annex M of the document.
ISO/IEC 9899:2024 – Information technology – Programming languages – C is available on the ANSI Webstore.