Crowbar: the good parts of C, with a little bit extra. **This is entirely a work-in-progress, and should not be relied upon to be stable in any way.** Crowbar is a language that compiles directly to [C99](https://en.wikipedia.org/wiki/C99), and aims to remove as many [footgun](https://en.wiktionary.org/wiki/footgun)s and as much needless complexity from C as possible while still being familiar to C developers. Ideally, a typical C codebase should be straightforward to rewrite in Crowbar, and any atypical C constructions not supported by Crowbar can be left as C. In principle, there's no reason it would be impossible to write a compiler directly for Crowbar, skipping the C step entirely, but that would take a lot of work. # Removals Some of the footguns and complexity in C come from misfeatures that can simply not be used. ## Footguns ### Almost Always The Wrong Thing - `goto` - Octal literals - Hexadecimal float literals - Wide characters - Digraphs - Prefix `++` and `--` - Chaining mixed left and right shifts (e.g. `x << 3 >> 2`) - Chaining relational/equality operators (e.g. `3 < x == 2`) - Mixed chains of bitwise or logical operators (e.g. `2 & x && 4 ^ y`) - The comma operator `,` ### Explicit Beats Implicit - `typedef` - Octal escape sequences - Using an assignment operator (`=`, `+=`, etc) or (postfix) `++` and `--` as components in a larger expression - The conditional operator `?:` - Preprocessor macros (but constants are fine) ## Needless Complexity ### Let The Compiler Decide - `inline` - `register` ### Who Even Cares - `restrict` - `volatile` - `_Imaginary` # Adjustments Some C features are footguns by default, so Crowbar ensures that they are only used correctly. - Unions are not robust by default. Crowbar only supports unions when they are [tagged unions](tagged-unions.md). C's syntax isn't perfect, but it's usually pretty good. However, sometimes it just sucks, and in those cases Crowbar makes changes. - C's variable declaration syntax is far from intuitive in nontrivial cases (function pointers, pointer-to-`const` vs `const`-pointer, etc). Crowbar uses [simplified type syntax](types.md) to keep types and variable names distinct. - `_Bool` is just `bool`, `_Complex` is just `complex` (why drag the preprocessor into it?) - Adding a `_` to numeric literals as a separator - All string literals, char literals, etc are UTF-8 # Additions ## Anti-Footguns - C is generous with memory in ways that are unreliable by default. Crowbar adds [memory safety guarantees](safety.md) to make correctness the default behavior. ## Trivial Room For Improvement - Binary literals, prefixed with `0b`/`0B` # Context - [Rust is not a good C replacement](https://drewdevault.com/2019/03/25/Rust-is-not-a-good-C-replacement.html) # cactus's Blog Posts - [Crowbar: Defining a good C replacement](https://www.boringcactus.com/2020/09/28/crowbar-1-defining-a-c-replacement.html) - [Crowbar: Simplifying C's type names](https://www.boringcactus.com/2020/10/13/crowbar-2-simplifying-c-type-names.html) # Syntax [Read the Syntax chapter of the spec.](syntax.md) # Semantics TODO [![Creative Commons BY-SA License](https://i.creativecommons.org/l/by-sa/4.0/80x15.png)](http://creativecommons.org/licenses/by-sa/4.0/)