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).
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,deferunder 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_tsuffix. - 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.