Expressions
Temporary address¶
Expressions work like in C, with one exception: it is possible to take the address of a temporary. This uses the operator && rather than &.
Consequently, this is valid:
A pointer created with && is only valid until the end of the current function. In other words, you should never return the pointer created by && from a function as it will never be safe to use.
Well-defined evaluation order¶
Expressions have a well-defined evaluation order:
- Binary expressions are evaluated from left to right.
- Assignment occurs right to left, so
a = a++would result inabeing unchanged. - Call arguments are evaluated in parameter order.
Compound literals¶
C3 has C's compound literals:
Arrays follow the same syntax:
Note that when it's possible, inferring the type is allowed and preferred, so we have for the above examples:
One may take the address of temporaries, using&& (rather than & for normal variables). This allows the following: Passing a slice
fn void test(int[] y) { ... }
// Using &&
test(&&(int[3]){ 1, 2, 3 });
// Explicitly slicing:
test(((int[3]){ 1, 2, 3 })[..]);
// Using a slice directly as a temporary:
test((int[]){ 1, 2, 3 });
// Same as above but with inferred type:
test({ 1, 2, 3 });
Passing the pointer to an array
fn void test1(int[3]* z) { ... }
fn void test2(int* z) { ... }
test1(&&(int[3]){ 1, 2, 3 });
test2(&&(int[3]){ 1, 2, 3 });
Constant expressions¶
In C3 all constant expressions are guaranteed to be calculated at compile time. The following are considered constant expressions:
- The
nullliteral. - Boolean, floating point and integer literals.
- The result of arithmetics on constant expressions.
- Compile time variables (prefixed with
$) - Global constant variables with initializers that are constant expressions.
- The result of macros that do not generate code and only use constant expressions.
- The result of a cast if the value is cast to a boolean, floating point or integer type and the value that is converted is a constant expression.
- String literals.
- Initializer lists containing constant values.
Some things that are not constant expressions:
- Any pointer that isn't the
nullliteral, even if it's derived from a constant expression. - The result of a cast except for casts of constant expressions to a numeric type.
- Compound literals - even when values are constant expressions.
Including binary data¶
The $embed(...) function includes the contents of a file into the compilation as a constant array of bytes:
The result of an embed works similar to a string literal and may implicitly convert to a char*, void*, char[], char[*] or String.
Limiting length¶
It's possible to limit the length of what is included using the optional second parameter.
Failure to load at compile time and defaults¶
Usually it's a compile time error if the file can't be included, but sometimes it's useful to only optionally include it. If this is desired, declare the left hand side an Optional:
my_image will be an optional io::FILE_NOT_FOUND~ if the image is missing.
This also allows us to pass a default value using ??: