Expressions
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:
fn void test(int* x) { ... }
test(&&1);
// In C:
// int x = 1;
// test(&x);
Compound literals
C3 has C's compound literals, but unlike C's cast style syntax (MyStruct) { 1, 2 }
,
it uses C++ syntax: MyStruct { 1, 2 }
.
struct Foo
{
int a;
double b;
}
fn void test(Foo x) { ... }
...
test(Foo { 1, 2.0 });
Arrays follow the same syntax:
fn void test(int[3] x) { ... }
...
test(int[3] { 1, 2, 3 });
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 }));
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
null
literal. - 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 does not generate code and only uses 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
null
literal, 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.