1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
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).
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`
|