Maximal min() and max()

Macro complexity and compile-time blowups

  • Original topic: Linux kernel min/max macros exploding to tens of megabytes of generated C, slowing compilation.
  • Several commenters share similar experiences: sophisticated “safe arithmetic” or comparison macros can expand to GB-sized translation units or crash compilers.
  • The core cause: heavy preprocessor use to emulate generics and type checks, leading to exponential macro expansion in nested calls (e.g., min(min(a,b),c)).

Why macros instead of functions?

  • Macros work in constant-expression contexts (e.g., array sizes); C lacks constexpr-style functions.
  • C has no true type-generic functions; C11 _Generic helps but still requires macros for dispatch and doesn’t naturally support mixed-type comparisons.
  • The kernel wants type-safe min/max that:
    • Work with mixed integer types.
    • Detect unsafe implicit conversions.
    • Preserve constant-expression usability.

Type system, implicit conversions, and safety

  • Many argue that C’s implicit numeric conversions are a fundamental design flaw that force these macro contortions.
  • Comparisons with Rust and Haskell: explicit casts preferred; fewer “magic” promotions.
  • C++ is criticized for adding even more implicit-conversion paths, though it can disable them for user types.

C vs C++ vs Rust (and other languages)

  • Some say the macro mess illustrates C’s limitations and argue for languages with real generics and hygienic macros.
  • Others respond that switching a massive kernel codebase to another language for “better min/max” is unrealistic.
  • C++ is debated:
    • Pro: templates and constexpr could express safe min/max more cleanly.
    • Con: incompatibilities with C99 features, template compile-time costs, extra UB “landmines”, and social/maintenance concerns.
  • Rust is seen as more purpose-built for kernels, but its dependency culture, macros, and compile times draw criticism.

Alternatives proposed

  • Define per-type min_*/max_* functions or macros; pushback: weakens typedef usability and doesn’t solve mixed-type safety.
  • Use _Generic plus GNU typeof to dispatch to typed inline functions; still complex and may not fix constant-expression needs or expansion size.
  • Add compiler builtins or even standard-library min/max that handle type safety and constant contexts; some see this as the cleanest long-term solution, but it doesn’t help older compilers.

Meta-discussion on language and tooling design

  • The issue is used as an example of:
    • How much work C programmers do to avoid higher-level language features.
    • How better macro systems (hygienic, AST-level) or DSLs could avoid textual blowups.
    • How large, conservative projects incrementally evolve via compiler extensions rather than language swaps.