aboutsummaryrefslogtreecommitdiff
path: root/vs-c.md
blob: 116870a73eab284a8200aab93b1700529b72cd23 (plain)
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
71
72
# Comparison to C

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`
-   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
-   Octal literals have a `0o` prefix (never `0O` because that looks nasty)

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