Skip to content

Undefined Behaviour

Like C, C3 uses undefined behaviour. In contrast, C3 will trap - that is, print an error trace and abort – on undefined behaviour in debug builds. This is similar to using C with a UB sanitizer. It is only during release builds that actual undefined behaviour occurs.

In C3, undefined behaviour means that the compiler is free to interpret undefined behaviour as if behaviour cannot occur.

In the example below:

uint x = foo();
uint z = 255 / x;
return x != 0;

The case of x == 0 would invoke undefined behaviour for 255/x. For that reason, the compiler may assume that x != 0 and compile it into the following code:

return true;

As a contrast, the safe build will compile code equivalent to the following.

uint x = foo();
if (x == 0) trap("Division by zero")
return true;

List of undefined behaviours

The following operations cause undefined behaviour in release builds of C3:

operationwill trap in safe builds
int / 0Yes
int % 0Yes
reading explicitly uninitialized memoryPossible*
array index out of boundsYes
dereference nullYes
dereferencing memory not allocatedPossible*
dereferencing memory outside of its lifetimePossible*
casting pointer to the incorrect arrayPossible*
violating pre or post conditionsYes
violating assertsYes
reaching unreachable() codeYes

* “Possible” indicates trapping is implementation dependent.

List of implementation dependent behaviours

Some behaviour is allowed to differ between implementations and platforms.

operationwill trap in safe buildspermitted behaviour
comparing pointers of different provenanceOptionalAny result
subtracting pointers of different provenanceOptionalAny result
shifting by more or equal to the bit widthYesAny result
shifting by negative amountYesAny result
conversion floating point <-> integer type is out of rangeOptionalAny result
conversion between pointer types produces one with incorrect alignmentOptionalAny result / Error
calling a function through a function pointer that does not match the functionOptionalAny result / Error
attempt to modify a string literalOptionalPartial modification / Error
modifying a const variableOptionalPartial modification / Error

List of undefined behaviour in C, which is defined in C3

Signed Integer Overflow

Signed integer is always wrapped using 2s complement.

Modifying the intermediate results of an expression

Behaves as if the intermediate result was stored in a variable on the stack.