Files
vlibc/STYLEGUIDE.md
T
huntedbytheirs 180c1107b6 Add vlibc scaffold, build system, and documentation
Establish the repository layout per Vox guidelines (layouts/C.md,
building/C.md): Autotools build (GCC-only, C23), five compatibility
profiles (--enable-onlyposix/--enable-muslmimic/--enable-muslext/
--enable-spoof, default vlibc), alongside/overwrite install methods,
vlibc-gcc/vlibc-clang drivers, static-linking requirement (except
spoof), benchmark harness, and tooling (.clang-format/.clang-tidy/
.clangd + compile_commands.json).
2026-08-31 17:06:01 -04:00

2.6 KiB

Styleguide

This file is the source of truth for how vlibc code looks. .clang-format is generated from / kept in sync with it.

Language

  • C23 is the default standard; C2y (C29) is opt-in via --enable-c29.
  • GCC only. Compiler extensions (__attribute__, statement expressions, defer under C2y) are permitted and encouraged where they improve clarity or performance.

Formatting

  • 4-space indent, no tabs.
  • 100-column limit.
  • Allman braces: opening brace on its own line, for functions and blocks.
  • Always use braces, even for single-statement blocks (avoids goto fail-style bugs and matches .clang-tidy).
  • Pointer and qualifier attach to the name: const char *s, int *p.
  • Spaces around binary operators; no space after unary operators.

The one exception to Allman braces is the C++ linkage guard: extern "C" { keeps its opening brace attached (encoded as AfterExternBlock: false in .clang-format), because that is the idiomatic form every C header uses.

int
foo(const char *s, size_t n)
{
    if (n == 0)
    {
        return 0;
    }

    return (int)(s[0] == 'x');
}

Naming

  • Functions and variables: snake_case.
  • Types: snake_case (struct tags); typedefs avoid the POSIX-reserved _t suffix.
  • Macros and constants: UPPER_SNAKE_CASE.
  • Public identifiers are prefixed vlibc_ to avoid collisions.
  • Identifiers beginning with _ (or __, or _[A-Z]) are reserved for the implementation and the C/POSIX standards — do not introduce new ones.

Include guards

Public headers use traditional include guards:

#ifndef VLIBC_H
#define VLIBC_H
...
#endif /* VLIBC_H */

#pragma once is a widely supported extension but is deliberately not used: it relies on compiler-specific path canonicalization and can mis-deduplicate headers reachable through symlinks or bind mounts. For a libc whose headers are consumed in many toolchain configurations, explicit guards are the robust default.

Compiler intent

Public declarations annotate intent so the compiler can optimize statically linked binaries (see docs/overview.md):

  • __attribute__((const)) — result depends only on arguments.
  • __attribute__((pure)) — no side effects; may read memory.
  • __attribute__((always_inline)), __attribute__((leaf)), __attribute__((malloc)), __attribute__((access, ...)) — as appropriate.

Every public function carries the tightest correct attribute.

Error handling

  • No empty blocks; no silent failure.
  • Library functions return errors via return codes or errno; they never terminate the caller's process.