1. Comparison to C

What differentiates Crowbar from C?

1.1. Removals

Some of the footguns and complexity in C come from misfeatures that can simply not be used.

1.1.1. Footguns

Some constructs in C are almost always the wrong thing.

  • goto

  • 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)

  • Subtly variable-size integer types (int instead of int32_t, etc)

  • 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)

1.1.2. 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

1.2. Adjustments

Some C features are footguns by default, so Crowbar ensures that they are only used correctly.

  • Unions are not robust by default. Crowbar offers two types of union declarations: a tagged union (the default) and a fragile union for interoperability purposes.

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 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

  • Octal literals have a 0o prefix (never 0O because that looks nasty)

1.3. Additions

1.3.1. Anti-Footguns

  • C is generous with memory in ways that are unreliable by default. Crowbar adds memory safety conventions to make correctness the default behavior.

  • C’s conventions for error handling are unreliable by default. Crowbar adds error propagation to make correctness the default behavior.

1.3.2. Trivial Room For Improvement

  • Binary literals, prefixed with 0b/0B