aboutsummaryrefslogtreecommitdiff
path: root/vs-c.rst
blob: 73d0653578db7c7ba5d3445357ea4145fdc493f6 (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
73
74
75
76
77
78
79
80
81
***************
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 offers two types of union declarations: a :crowbar:ref:`tagged union <RobustUnionDefinition>` (the default) and a :crowbar:ref:`fragile union <FragileUnionDefinition>` 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 :crowbar:ref:`simplified type syntax <Type>` 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 :doc:`memory safety conventions <safety>` to make correctness the default behavior.
*   C's conventions for error handling are unreliable by default.
    Crowbar adds :doc:`error propagation <errors>` to make correctness the default behavior.

Trivial Room For Improvement
----------------------------

*   Binary literals, prefixed with ``0b``/``0B``