Files
fastwc/STYLEGUIDE.md
T
huntedbytheirs c4d4f0b713 first: setup
setting up repo.
2026-08-29 13:48:15 -04:00

3.8 KiB

fastwc Style Guide

The style is the law. GNU wc can afford to look like a committee designed it — it was. We're one file, one purpose, one opinion.

The language

  • C99 with POSIX. _POSIX_C_SOURCE 200809L. We target the standard, not a compiler vendor's mood.
  • Zero warnings with -Wall -Wextra. A warning is a bug you haven't fixed yet. Fix it.
  • No compiler-specific extensions unless they're guarded and the benchmark gets faster because of it. __builtin_popcountll is the one exception — it's the price of admission on every compiler that matters, and the benchmark proves it.

Format

  • 4 spaces. Not tabs, not 8 spaces. GNU uses tabs because GNU was written in 1985 by people who had strong opinions about typewriters.
  • 80 columns. If your line is longer, your idea is longer than it needs to be.
  • Braces on the next line (Allman). Everywhere. Functions, blocks, switch cases. Consistency is the only religion here, and we're devout.
  • Snake case for everything. count_stream, ws_tab, nread. No CamelCase — that's for languages that need help knowing what a word is.

Structure

  • One file: src/main.c. See CONTRIBUTING.md rule 6. This is not a suggestion.
  • Everything is static. The binary exports nothing. We're not a library, we're a verdict.
  • Types end in _t. counts_t, and not much else. GNU has a type for everything and a committee to name it. We have counts, and we count.
  • No globals except what's truly process-wide. flags and ws_tab live at file scope because they're the program's identity. Everything else gets passed around like it's hot.

The hot path

count_stream(), count_newlines(), count_words() are the product. The rest of the file is just the packaging.

  • Fixed stride. No per-token function calls. No isspace() in a loop — that's what the lookup table is for.
  • No allocation, no locks, no syscalls in the counting loop. The fread is the only syscall, and it's not yours to add to.
  • Branchless where it costs nothing. A predictable branch is fine; a mispredicted one is a lie you told the CPU.
  • The buffer is static, 128 KiB, and never grows. GNU's wc reads in chunks too — ours just doesn't make a ceremony of it.

Counts

  • long long for everything that counts. Files can be bigger than your opinions. Signed, because overflow should scream, not wrap.
  • Lines are '\n's. Not "lines of text," not "records." A file without a trailing newline has fewer newlines than it has lines, and that's correct. GNU agrees with us on this one, so it must be right.
  • Words are whitespace-delimited runs. The lookup table decides what whitespace is; the popcount decides how many words; you don't get an opinion.

Errors

  • fastwc: <file>: <message> on stderr, and keep going. GNU wc fails gracefully across multiple files, and we'll credit them that one thing. Then we'll be faster at it.
  • Exit 1 if anything failed, 0 otherwise. No drama, no EXIT_FAILURE poetry.

Comments

  • Only when the code can't speak for itself. The SWAR newline counter in count_newlines() gets a comment because (x ^ nl) & cl is a sentence in a language you don't speak yet. i++ does not get a comment.
  • No commented-out code. The dead don't get to live in the file.
  • No TODO without a date. A TODO without a date is a promise you plan to break.

What the style is not

  • It is not GNU's style. GNU's style was written by a committee, ratified by a foundation, and translated into fourteen languages.
  • It is not "whatever your editor defaults to." Your editor has opinions. So do we. Ours are right.
  • It is not negotiable in review. If a PR violates the style, the PR is a rewrite request with extra steps.