CFoundations

C23 Modern C: auto, nullptr, constexpr, typeof, Attributes & Library Improvements

TT
TopicTrick Team
C23 Modern C: auto, nullptr, constexpr, typeof, Attributes & Library Improvements

C23 Modern C: auto, nullptr, constexpr, typeof, Attributes & Library Improvements


Table of Contents


How to Enable C23

bash

auto: Type Inference Without the Verbosity

C23 repurposes the old, unused auto storage class specifier as a type inference keyword. The compiler deduces the type from the initializer, eliminating verbose type repetition:

c

[!NOTE] Unlike C++, C23 auto cannot be used for function parameters or return types. It applies only to local variable declarations with initializers.


nullptr: The Type-Safe Null Pointer Constant

The old NULL macro is defined as 0 or (void*)0 — both are integers when used in non-pointer contexts, causing potential ambiguity. C23 introduces nullptr, a keyword of type nullptr_t that can only be used as a null pointer:

c

nullptr of type nullptr_t is implicitly convertible to any pointer type (including function pointers), but is NOT an integer — fixing the historical ambiguity.


constexpr: Compile-Time Constants

C23's constexpr is more limited than C++'s version but still extremely valuable. It declares compile-time constant variables (unlike #define, which is a preprocessor text substitution):

c

typeof and typeof_unqual

typeof(expression) yields the type of its argument at compile time — invaluable for writing truly generic macros without requiring _Generic:

c

Standardized Attributes

C23 standardizes attributes using [[attribute]] syntax (borrowed from C++). Previously, compilers had vendor-specific syntax (__attribute__((...))):

c

Enhanced Numerics: Binary Literals and Digit Separators

c

Improved Standard Library

memset_explicit: Secure Zeroing

Regular memset for zeroing sensitive data (passwords, encryption keys) can be optimized away by the compiler since the memory is "dead" after zeroing. memset_explicit is guaranteed never to be optimized away:

c

strdup and strndup (Standardized)

Previously POSIX extensions, now part of C23:

c

stdbit.h: Portable Bit Operations

C23 adds <stdbit.h> with standardized, efficient bit counting and manipulation functions — replacing the need for vendor-specific __builtin_popcount etc.:

c

These functions compile to single CPU instructions on x86-64 (POPCNT, BSR, LZCNT, TZCNT).


Removed and Deprecated Features

C23 removes features that were already deprecated or "optional" in C11:

RemovedReplacement
K&R style function definitions (int f(a,b) int a, b; {...})Modern: int f(int a, int b) {...}
Implicit int return typeAlways specify return type explicitly
gets() (already removed in C11)Use fgets()
Trigraph sequences (??=#)Use actual characters
Unprototyped function declarationsAlways prototype functions

C23 vs C11 vs C99: Migration Guide

FeatureC99C11C23
bool, true, falseMacro via stdbool.hKeywordBuilt-in keyword
_Generic✅ Improved
nullptr
constexpr
auto (type inference)
typeofGNU extensionGNU extension✅ Standardized
Binary literals 0b...GNU extensionGNU extension✅ Standardized
Digit separators 1'000
[[attributes]]Mixed✅ Full set
memset_explicit
strdupPOSIXPOSIX✅ Standardized
<stdbit.h>

Frequently Asked Questions

Is C23 backwards compatible with C11/C99 code? Almost entirely. The only breaking changes are removal of K&R style function definitions and trigraphs — both of which are extremely rare in modern code. Virtually all C11 and C99 code compiles cleanly under C23.

When will compilers fully support C23? GCC 14+ and Clang 18+ have comprehensive C23 support. MSVC (Microsoft Visual C++) has partial support. Check cppreference.com's C23 compiler support table for the current status per feature.

Can I use C23's auto in the same file as C++ code? No — C and C++ are compiled separately. auto in C23 means type inference (same as in C++11+), but the rules differ. In C++, auto can be used for function return types and template parameters; in C23, it cannot.

Is constexpr in C23 the same as in C++? No. C23's constexpr is more limited — it can only be applied to variables and only for values that can be computed at compile time from constant expressions. C++'s constexpr can additionally be applied to functions and enables compile-time function evaluation.


Key Takeaway

C23 demonstrates that C is still actively evolving. By adopting auto for type inference, nullptr for null safety, constexpr for zero-cost compile-time constants, typeof for powerful generic macros, and standardized [[attributes]] for optimization hints, you get a modern, expressive language that retains every bit of C's legendary performance.

These are not cosmetic changes — they directly reduce bugs (nullptr prevents null-as-integer confusion), improve tooling (constexpr variables are visible in debuggers), and enable better compiler optimization (attributes help the compiler understand your code's intent).

Read next: C Security & Hardening: Defeating Buffer Overflows →


Part of the C Mastery Course — 30 modules from C basics to expert systems engineering.