C23: A Slightly Better C

C23, the latest revision of the C language standard, introduces a set of incremental features such as `auto` type deduction, `typeof`, a keyword form of `static_assert`, cleaner initialization syntax, and removal of legacy constructs like trigraphs and K&R-style function definitions. Commenters are split on whether these changes meaningfully improve C: some welcome better generic macros, safer checked arithmetic, and closer alignment with existing compiler extensions and C++, while others see them as superficial tweaks that don’t address long-standing issues like strings, modules, and safer resource management. The conversation also situates C23 in a broader landscape where many new systems projects favor C++ or Rust, and where alternative languages (Zig, D, Nim, Ada, etc.) compete to offer safer or more ergonomic C interop.

Auto, typeof, and “generics” in C23

  • Reusing auto is seen by some as an odd choice; many expect it to be a style “no‑no” in serious C code, unlike in C++.
  • Others argue it’s genuinely useful in C:
    • Avoids verbose type names and struct/enum prefixes.
    • Helps with generic macros (e.g., SWAP(a,b) using auto tmp = a;) and with fixed‑width integer types.
    • Standardizes existing __auto_type extensions.
  • typeof is also added; some note you can now write const typeof(var1) tmp = var1;.
  • Debate over whether _Generic really counts as “generics”: some see it as overloading/switch-on-type, not parametric data structures; others say it still meets the bar for “generic.”

Other C23 language tweaks

  • static_assert becomes a keyword; C11 already had _Static_assert and a macro, but now it’s usable without <assert.h>.
  • func() is now explicitly equivalent to func(void), and unnamed parameters are allowed.
  • Struct initialization with {} (zero-init) is now valid (struct foo x = {};), aligning with C++.
  • Removal of trigraphs and old K&R‑style function declarations is welcomed as cleaning up historical quirks.
  • Some wish C23 had a built‑in defer/RAII feature; such a proposal exists but is still “exploratory.”

Toolchain and compiler support

  • Reference to cppreference shows GCC 13 has comparatively broad C23 support; Clang lags on several features.
  • Explanations offered: LLVM’s modular design and corporate forks slow front‑end evolution; big contributors focus on backends or other languages.
  • Pelles C reportedly supports nearly all C23 features, including #embed.
  • MSVC historically neglected C, but more recently supports C17 (minus some optional C99 features); future C23 timing is unclear.

C vs C++ and language philosophy

  • Some argue C++ is already “a better C” and that C23 is mostly backporting C++ features.
  • Others respond that C and C++ now serve different domains; C++’s complexity, meta‑programming, and hidden code generation are seen as inappropriate for some embedded/low‑level use cases.
  • Analogies vary: from “C++ is a cybertruck to C’s bicycle” (criticized as inaccurate) to “C is hand tools, C++ adds power tools.”
  • Debate over exceptions and RAII in embedded: some say RAII is straightforward and helpful; others worry about less explicit object lifetimes.

Headers, modules, and API surface

  • Some wish C had true modules/imports instead of headers, to avoid duplication and speed builds, possibly with import alongside legacy #include.
  • Others like C’s separate header/implementation split for clearly exposing a public API; note that this is orthogonal to whether the language has a module system.
  • There’s discussion that stronger modules might break some C/C++ interoperability, which is politically sensitive.

Memory‑safe alternatives and C FFI

  • A long subthread explores “small, stable, memory‑safe languages with excellent C FFI and no big performance loss.”
  • Candidates mentioned include Zig, D, Rust, Nim, V, Vala, LuaJIT, Ada, various Schemes and Lisps, Swift, Julia, and Go.
  • Tradeoffs highlighted:
    • True memory safety often implies GC or Rust‑style borrowing; both complicate FFI and/or simplicity.
    • Easy, zero‑overhead C FFI tends to undermine strong safety guarantees (bugs can leak in from C).
    • Several commenters argue the exact wish list may be impossible to satisfy fully; you can at best approximate it with different compromises.