# MaJerle/c-code-style: C11 Rules and clang-format for Embedded C Projects

> MaJerle/c-code-style is a C11 coding-rules document by Tilen MAJERLE that pairs written conventions with a .clang-format file for automated enforcement and a Claude Code skill for AI-assisted checking in contributors' development environments.

**MaJerle/c-code-style** — Recommended C code style and coding rules for standard C99 or later. Comes with AI agent skill to write, edit and format the code.

- Repository: https://github.com/MaJerle/c-code-style
- Website: http://majerle.eu
- Stars: 1,351 · Forks: 268
- Language: C
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/majerle-c-code-style

## One style document, two enforcement channels

MaJerle/c-code-style exists to solve a recurring problem in open-source embedded C development: contributors to Tilen MAJERLE's libraries arrived with their own formatting habits, turning code review into debates about whitespace and brace placement. The repository centers on a single document, CODING_RULES.md, which the README describes as the authoritative style guide. The README.md at the repository root is a symlink to CODING_RULES.md so GitHub renders it on the front page; contributors who adopt the rules are instructed to copy CODING_RULES.md into their own repository rather than README.md, to avoid overwriting their project's own readme file.

Alongside the document, the repository ships a .clang-format file that encodes the same rules in machine-readable form for automated enforcement during editing or in CI pipelines. As of the September 2026 push, a Claude Code skill directory at .claude/skills/c-code-style/ and an AGENTS.md file extend enforcement to AI coding sessions. The repository also includes template.c and template.h showing the expected layout for a module's source and header files. The target audience is C library maintainers, embedded systems developers, and contributors to MAJERLE's own projects.

## Spacing, braces, and naming: the concrete rules

The guide targets the C11 standard and mandates four-space indentation with no tabs. Every control keyword (if, while, for, do) takes exactly one space before its opening parenthesis; function calls take none:

```c
/* OK */
if (condition)
while (condition)
for (init; condition; step)
do {} while (condition)

/* Wrong */
if(condition)
while(condition)
for(init;condition;step)
do {} while(condition)
```

Opening curly braces belong on the same line as the keyword. Variable and function names use only lowercase letters and the _ separator. Variable names must be at least three characters long. The guide introduces two explicit name prefixes: prv_ for static functions that are private to a single module, and libname_int_ (or the shorter libnamei_) for functions that modules within the same library call internally but that application code should not use. Single spaces around assignment and comparison operators and after every comma are required. The guide uses RFC 2119 keywords throughout (MUST, SHOULD, MAY), and explicitly reserves __ and _ prefixes (double and single) for the C language itself.

## Adopting CODING_RULES.md and running clang-format

To adopt the guide, copy CODING_RULES.md and the .clang-format file from the repository root into the target project. When clang-format runs, it searches upward from each source file until it finds a .clang-format file, so placing it at the project root covers all subdirectories without extra configuration. The README states that clang-format version 20.x or later is required; earlier versions may parse the same .clang-format file differently and produce inconsistent output.

The following example from the README shows the correct placement of the opening brace in a for loop, along with a form the guide marks as wrong:

```c
size_t idx;
for (idx = 0; idx < 5; ++idx) {           /* OK */
}
for (idx = 0; idx < 5; ++idx){            /* Wrong */
}
```

VSCode can invoke clang-format when a file is saved by enabling format-on-save and pointing to the clang-format binary. The repository includes INSTALL.md for additional setup details. The .github/ directory indicates that CI configuration is present, and the README table of contents lists a section on continuous integration with GitHub Actions, though those steps are not detailed in the README itself.

## Embedded-specific initialization rules

One section of CODING_RULES.md addresses a failure mode found mainly on embedded targets. The guide instructs developers to avoid initializing global variables with explicit values at their declaration and to use a dedicated init function instead:

```c
static int32_t global_var_a;       /* OK */
static int32_t global_var_b = 4;   /* Avoid if startup and linker scripts may not initialize it properly */

void
my_module_init(void) {
    global_var_a = 0;
    global_var_b = 4;
}
```

The reasoning: on embedded targets, RAM may reside in non-standard memory sections defined by a custom linker script. If startup code does not explicitly initialize those sections, compiler-level initial values declared at the variable definition may have no effect at runtime. An explicit init function called from the startup sequence is the only reliable approach in that environment. This guidance is specific to firmware and microcontroller development. On hosted platforms where the C runtime guarantees zero-initialization of static storage, this constraint carries no practical benefit, and teams working exclusively on Linux or Windows applications can treat the init-function rule as optional context.

## The Claude Code skill and AGENTS.md integration

The repository ships an AGENTS.md file at the root and a Claude Code skill directory at .claude/skills/c-code-style/. According to the README, the skill checks that clang-format is available and then runs it on relevant files using the repository's .clang-format rules. A Claude Code session in a project that carries both files can invoke formatting enforcement without a separate manual step. The repository description explicitly states the project comes with an AI agent skill to write, edit, and format code, which positions clang-format integration as a first-class feature for AI-assisted development rather than a bolt-on.

The .claude-plugin/ directory at the repository root suggests additional plugin support beyond the skill itself. MAJERLE's AGENTS.md approach means contributors using Claude Code in their own forks or libraries built on this standard can get automated formatting feedback as part of their normal editing workflow, rather than waiting for a CI run to catch violations.

## Where the guide does not extend

MaJerle/c-code-style is a C-only document. It gives no guidance on C++ constructs such as classes, templates, exceptions, or namespaces, so projects that mix C and C++ under the same style enforcement will need a separate guide for the C++ portions. The document also says nothing about project directory layout, build system configuration, Makefiles, or test structure. Its scope is confined to in-file code style.

The README table of contents references a documentation section, but the documentation conventions are not expanded in the visible README text. Similarly, the GitHub Actions CI section appears in the table of contents but is not detailed, so teams that need a complete pipeline must consult the .github/ directory or INSTALL.md directly. The guide is also a single concrete choice. Teams already committed to a different indent width or brace convention would need to reformulate their existing .clang-format file before any benefit is possible, which may not be practical for large existing codebases.

## The Linux kernel style as the primary alternative

The Linux kernel coding style is the closest well-known alternative for C developers. It uses eight-space indentation with hard tabs, which makes deep nesting immediately visible as a structural problem by consuming screen width quickly. MAJERLE's guide uses four spaces and no tabs, which is more compatible with editors and code views configured for standard four-column indentation. Both guides place opening braces on the same line as control statements and require lowercase naming with _s. The Linux style is not distributed as a clang-format configuration by the kernel project itself, though community-maintained configurations exist.

Google's C++ style guide targets C++ primarily and is not a direct substitute for a C-only project. MISRA C belongs to a different category entirely: it defines formal compliance rules for safety-critical embedded systems, requires dedicated static analysis tools, and carries commercial licensing for the specification document. MAJERLE's guide is an open-source set of conventions for library-quality C code, not a safety standard.

## Maintenance status and MIT license

The repository's last push was on 2026-09-09. The project is not archived. There are no GitHub releases; changes accumulate on the main branch and are tracked there. The MIT license terms allow copying CODING_RULES.md and .clang-format into commercial and proprietary projects without obligation to publish modifications or attribute the original author in source files, beyond what MIT requires. This makes it practical to embed the document and configuration in a proprietary embedded SDK without legal complications.

The clang-format version requirement is the primary compatibility constraint for new adopters. Teams running toolchains based on LLVM 18 or 19 would need to upgrade to version 20.x before the configuration file produces consistent output. The repository history and the presence of a .release-please style .github/ directory suggest the project follows a structured update approach, but no semantic version tags have been published through GitHub Releases.

## Conclusion

Teams maintaining C11 embedded firmware or contributing to Tilen MAJERLE's open-source libraries can adopt the guide by copying CODING_RULES.md and .clang-format into their project root, then enforcing the rules with clang-format version 20.x or later. Projects already committed to a different indent width, or any codebase written primarily in C++, gain little here. Before adopting, verify that clang-format 20.x is available in your toolchain, because earlier versions may produce different output from the same configuration file.

## FAQ

### How do I add MaJerle/c-code-style to an existing C project?

The README instructs you to copy CODING_RULES.md and the .clang-format file from the repository root into your project. Place .clang-format at the project root so clang-format finds it when formatting any file in the tree. The INSTALL.md file in the repository provides additional setup steps.

### What version of clang-format does MaJerle/c-code-style require?

The README states that clang-format version 20.x or later is required. Earlier versions may interpret the .clang-format configuration file differently and produce formatting output inconsistent with the written rules.

### Does MaJerle/c-code-style cover C++ code?

The guide targets C11 only. The README and CODING_RULES.md focus exclusively on C constructs and do not address C++ features. Projects that mix C and C++ would need a separate style document for their C++ code.

## Sources

- [Issues](https://github.com/MaJerle/c-code-style/issues)
- [License: MIT](https://github.com/MaJerle/c-code-style/blob/main/LICENSE)
- [MaJerle/c-code-style on GitHub](https://github.com/MaJerle/c-code-style)
- [Project website](http://majerle.eu)
- [README](https://github.com/MaJerle/c-code-style/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/majerle-c-code-style
