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

84 lines
2.6 KiB
Markdown

# 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.
```c
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:
```c
#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.