You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add all unchecked_* operations corresponding to -no-*-checks flags
Comparisons: unchecked_less, unchecked_less_eq, unchecked_greater, and unchecked_greater_eq
Division by zero: unchecked_div
Dereference: unchecked_dereference
Subscript: unchecked_subscript
Also fixed a bug in the code that identified attempts to assign to a pointer
Cpp2 aims to be safe by default, usually entirely at compile time, and when needed at run time.
5
+
6
+
When Cpp2 rejects unsafe code (e.g., signed/unsigned comparison) or ensuring safety can require run-time checks (e.g., subscripts bounds checks), you can opt out as needed in two ways:
7
+
8
+
- at a specific place in your code, using `unchecked_*` functions (these are in namespace `cpp2::`, but can be used unqualified from Cpp2 code)
9
+
- for a whole source file, using `-no-*-checks` switches
10
+
11
+
Nearly always, you should opt out at a specific place in your code where you are confident the result is okay, and if there is a run-time check you have measured that the performance difference matters such as in a hot loop.
Comparing signed and unsigned integer values directly using `<`, `<=`, `>`, or `>=` can give wrong results, and so such comparisons are rejected at compile time.
17
+
18
+
To disable this check at a specific place in your code, use the appropriate `unchecked_cmp_*` function instead of the operator notation: `unchecked_cmp_less`, `unchecked_cmp_less_eq`,`unchecked_cmp_greater`, or `unchecked_cmp_greater_eq`.
19
+
20
+
For example:
21
+
22
+
```cpp title="Integer comparisons" hl_lines="7"
23
+
main: () = {
24
+
x: i32 = 42;
25
+
y: u32 = 43;
26
+
27
+
if x < y { } // unsafe, therefore error by default
28
+
29
+
if unchecked_cmp_less(x,y) { } // ok, explicit "trust me" opt-out
30
+
}
31
+
```
32
+
33
+
To disable these checks for the entire source file, you can use cppfront's `-no-comparison-checks` switch:
34
+
35
+
```bash title="Disable prevention of mixed-sign integer comparisons" hl_lines="3"
36
+
cppfront myfile.cpp2 # mixed-sign int comparisons banned
37
+
38
+
cppfront myfile.cpp2 -no-comparison-checks # mixed-sign int comparisons allowed
39
+
```
40
+
41
+
42
+
### <aid="division-by-zero"></a> Division by zero (run-time checked)
43
+
44
+
Dividing integers by zero is undefined behavior, and is rejected at run time by checking the denominator is nonzero.
45
+
46
+
To disable this check at a specific place in your code, use `unchecked_div`. For example:
47
+
48
+
```cpp title="Division by zero" hl_lines="7"
49
+
main: () = {
50
+
x := 42;
51
+
y := 0;
52
+
53
+
z := x/y; // unsafe, therefore run-time checked
54
+
55
+
w := unchecked_div(x,y) // ok, explicit "trust me" opt-out
56
+
}
57
+
```
58
+
59
+
To disable these checks for the entire source file, you can use cppfront's `-no-div-zero-checks` switch:
60
+
61
+
```bash title="Disable prevention of division by zero" hl_lines="3"
62
+
cppfront myfile.cpp2 # division by zero checked
63
+
64
+
cppfront myfile.cpp2 -no-div-zero-checks # division by zero not checked
Accessing an out of bounds subscript is undefined behavior, and is rejected at run time by checking the subscript is nonzero. For an expression `a[b]` where
96
+
97
+
-`a` is contiguous and supports `std::size(a)`, and
98
+
-`b` is an integral value
99
+
100
+
the cppfront compiler injects a check that **`0 <= b < std::size(a)`** before the call to `a[b]`.
101
+
102
+
To disable this check at a specific place in your code, use `unchecked_subscript`. For example:
@@ -2729,7 +2787,8 @@ CPP2_FORCE_INLINE constexpr auto cmp_mixed_signedness_check() -> void
2729
2787
{
2730
2788
static_assert(
2731
2789
program_violates_type_safety_guarantee<T, U>,
2732
-
"comparing bool values using < <= >= > is unsafe and not allowed - are you missing parentheses?");
2790
+
"comparing bool values using < <= >= > is unsafe and not allowed - are you missing parentheses?"
2791
+
);
2733
2792
}
2734
2793
elseifconstexpr (
2735
2794
std::is_integral_v<T> &&
@@ -2745,20 +2804,22 @@ CPP2_FORCE_INLINE constexpr auto cmp_mixed_signedness_check() -> void
2745
2804
// static_assert to reject the comparison is the right way to go.
2746
2805
static_assert(
2747
2806
program_violates_type_safety_guarantee<T, U>,
2748
-
"mixed signed/unsigned comparison is unsafe - prefer using .ssize() instead of .size(), consider using std::cmp_less instead, or consider explicitly casting one of the values to change signedness by using 'as' or 'cpp2::unchecked_narrow'"
2807
+
"mixed signed/unsigned comparison is unsafe - prefer using .ssize() instead of .size(), consider using std::cmp_less or similar instead, or consider explicitly casting one of the values to change signedness by using 'as' or 'cpp2::unchecked_narrow'"
0 commit comments