Initialization in C++ is bonkers (2017)

C++ initialization complexity and culture

  • Many commenters agree C++ initialization rules are confusing, error‑prone, and hard even for experienced developers to fully internalize.
  • The existence of a 278‑page book just on initialization is used humorously as “evidence” of how bad things are.
  • Some advocate working around the complexity by always writing = {} or default member initializers everywhere, though others say this masks real bugs and defeats tools.

Safety vs performance and undefined behavior

  • One camp wants C++ to default to safe, well‑defined initialization, treating uninitialized memory as an explicit opt‑in with special syntax or attributes.
  • Another camp defends the current freedom, arguing systems programming must allow uninitialized memory and UB to enable aggressive optimizations and tight control over performance, especially in embedded and high‑performance domains.
  • Several argue the performance gains from UB are often overestimated and not worth the security and debugging cost.
  • There’s discussion of a fundamental tension: compilers both catching programmer mistakes and accepting “suspicious” code the programmer claims is intentional.

Comparisons to Rust, Zig, C, and others

  • Rust is repeatedly cited as an example where variables must be definitely initialized before use, with Option and MaybeUninit for explicit opt‑outs; some praise this, others find Rust’s ownership and reference model burdensome or too “nerfed” for certain low‑level tasks.
  • Zig’s explicit undefined and “must initialize” rule is called out as a clean design.
  • C is seen as simpler than C++, but its abstract machine and UB are also described as subtle.
  • Some believe C++ remains the most expressive low‑level language in practice; others counter that Rust, D, ATS, or even Lisps/Haskell can match or exceed it.

Standards, C++26, and zero‑init proposals

  • Multiple comments note that C++26 is moving from UB for uninitialized reads toward “erroneous behavior” with defined patterns and required diagnostics; attributes like [[indeterminate]] and compiler flags like -ftrivial-auto-var-init are mentioned.
  • A strong proposal is to make zero‑initialization the default for automatic variables, with explicit syntax or attributes for leaving memory uninitialized. Supporters argue this removes a major footgun; critics worry about lost optimization opportunities and tool signal.
  • Backward compatibility is a major recurring argument: some insist new standards must not break large legacy codebases; others argue that clinging to old semantics prevents fixing well‑known design mistakes and that old code can simply stay on older standards.

RAII, constructors, and inherent complexity

  • Several point out that once you add constructors/destructors, resource ownership, and RAII to C, the language must track lifetimes, member construction, copying/moving, and exception paths, making initialization semantics inherently complex.
  • Some defend RAII as a uniquely powerful feature that justifies the complexity; others advocate designs that separate raw storage from resource management (arenas, POD‑only containers) to avoid pervasive O(n) init/cleanup costs.

Longevity of C++ and alternatives

  • There’s disagreement on whether C++ should “die” or will remain entrenched like COBOL and Fortran; many note its ongoing use in games, HPC, embedded, and OS‑level work.
  • Proposed successors (Rust, Zig, Carbon, cppfront/Cpp2) are discussed; none are seen as a clear drop‑in replacement yet, especially for all existing low‑level use cases.