Porting to GCC 14: C language issues

GCC 14’s stricter conformance to modern C standards is turning long-standing warnings—such as implicit `int`, undeclared functions, and some pointer mismatches—into errors, forcing updates across large codebases and build systems like autoconf. Commenters weigh the benefits of improved safety, clearer diagnostics, and long-delayed adoption of C99/C23 features (like variable-length array types) against the pain of breaking legacy and “portable” C that relied on pre-ANSI or compiler-specific behavior. The thread also delves into deeper language design issues, including integer and pointer type semantics, calling conventions, and why some C features evolved so slowly despite being standardized decades ago.

GCC 14’s Stricter C Defaults

  • GCC 14 turns several long-standing C warnings into errors (e.g., implicit function declarations, implicit int, some incompatible pointer uses).
  • Many commenters see this as overdue: these constructs have been effectively obsolete for decades and almost never intentional in modern code.
  • Others note breakage: old code (including IOCCC entries and historical GNU userland) will fail unless errors are downgraded. GCC still allows flags to restore old behavior.

Variable Length Arrays (VLAs) and C23

  • Thread discusses C99 (VLAs mandatory), C11 (VLAs optional), and C23 (VLA types mandatory again; VLA objects with automatic storage remain optional).
  • Clarified that compilers must support the syntax and semantics of variably-modified types (e.g., sizeof and offsetof on them), but can still omit stack-based VLAs.
  • Debate on implementation complexity: runtime-dependent layouts and typedefs introduce extra semantic machinery beyond “just alloca sugar.”
  • MSVC still lacks VLAs and skipped C99 entirely, limiting portable use of VLAs.

Porting Work in Distros

  • Fedora and others have already done large-scale cleanup to prepare for stricter defaults, heavily impacted by autoconf-generated tests that use dubious C code and hide warnings.
  • Main risk was “silent feature loss”: builds succeed but configure checks fail, disabling features. This led to config diffing approaches.
  • Clang/Xcode having stricter defaults and Gentoo’s upstreaming of fixes helped get consensus for tightening GCC.

Legacy C Constructs and Compilation Models

  • Pre-ANSI C allowed calling undeclared functions, treating them as returning int; worked “well enough” when sizeof(int) == sizeof(pointer).
  • Discussion on how one-pass compilers handled not-yet-declared functions and whether extra checking would imply a “second pass.”
  • Some suggest the language should officially support more flexible forward referencing, citing newer compiler infrastructures where it “just works.”

Integer Types, Word Size, and Style

  • Long thread on why int stayed 32-bit on 64-bit systems: backward compatibility, limited standard integer ladder, and existing code assumptions.
  • Arguments for and against ever making int 64-bit: portability vs. memory/cache footprint vs. clarity.
  • Distinction between “standard” integer types (char/short/int/long/long long) and “extended” integer types; note that stdint.h mostly typedefs the former, not truly new widths.
  • Diverging practices: some prefer fixed-width types (int32_t, int64_t), others prefer int + long long and avoid numbered types due to aesthetics and overload issues (in C++).

Function Pointers, void*, and Pointer Representations

  • Question why a function taking const char* cannot be used where a function pointer of type int (*)(const void*, const void*) is expected.
  • Standard forbids arbitrary function pointer conversions; C also lacks a generic function pointer type.
  • C11 guarantees void* and character pointers share representation and alignment; other pointer types may not, and function pointers can differ from object pointers.
  • Historical and exotic architectures with non-uniform pointer sizes and addressing modes are cited as reasons the standard remains strict.

Backward Compatibility vs. Niche Use Cases

  • Some criticize the “anti-C89” direction, arguing that removing implicit int harms creative polyglot uses (e.g., C/JavaScript dual code) with no clear benefit.
  • Majority view in the thread favors stronger defaults to prevent subtly broken code, with escape hatches for legacy or contest-style programs.