What differentiates Crowbar from C? # Removals Some of the footguns and complexity in C come from misfeatures that can simply not be used. ## Footguns Some constructs in C are 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 `,` Some constructs in C exhibit implicit behavior that should instead be made explicit. - `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 Some type modifiers in C exist solely for the purpose of enabling optimizations which most compilers can do already. - `inline` - `register` Some type modifiers in C only apply in very specific circumstances and so aren't important. - `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) (or declared and used with the `fragile` keyword). 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 conventions](safety.md) to make correctness the default behavior. - C's conventions for error handling are unreliable by default. Crowbar adds [error propagation](errors.md) to make correctness the default behavior. ## Trivial Room For Improvement - Binary literals, prefixed with `0b`/`0B`