SPC  Version 0.9.5
 All Files Functions Groups Pages
Functions

It is often helpful to group a set of statements together into a single function, which your code can then call as needed.

SPC supports functions with arguments and return values. Functions are defined using the syntax below.

[inline] return_type name(argument_list)
{
// body of the function
}

The return type is the type of data returned. In the C programming language, functions must specify the type of data they return. Functions that do not return data simply return void.

Additional details about the keywords inline, and void can be found below.

The argument list of a function may be empty, or may contain one or more argument definitions. An argument is defined by a type followed by a name. Commas separate multiple arguments. All values are represented as bool, char, int, long, struct types, or arrays of any type.

SPC supports specifying a default value for function arguments that are not struct or array types. Simply add an equal sign followed by the default value. Specifying a default value makes the argument optional when you call the function. All optional arguments must be at the end of the argument list.

int foo(int x, int y = 20)
{
return x*y;
}
task main()
{
printf("%d\n", foo(10)); outputs 200
printf("%d\n", foo(10, 5)); outputs 50
Wait(SEC_10); // wait 10 seconds
}

SPC also supports passing arguments by value, by constant value, by reference, and by constant reference. These four modes for passing parameters into a function are discussed below.

When arguments are passed by value from the calling function or task to the called function the compiler must allocate a temporary variable to hold the argument. There are no restrictions on the type of value that may be used. However, since the function is working with a copy of the actual argument, the caller will not see any changes the called function makes to the value. In the example below, the function foo attempts to set the value of its argument to 2. This is perfectly legal, but since foo is working on a copy of the original argument, the variable y from the main task remains unchanged.

void foo(int x)
{
x = 2;
}
task main()
{
int y = 1; // y is now equal to 1
foo(y); // y is still equal to 1!
}

The second type of argument, const arg_type, is also passed by value. If the function is an inline function then arguments of this kind can sometimes be treated by the compiler as true constant values and can be evaluated at compile-time. If the function is not inline then the compiler treats the argument as if it were a constant reference, allowing you to pass either constants or variables. Being able to fully evaluate function arguments at compile-time can be important since some SPC API functions only work with true constant arguments.

void foo(const int x)
{
x = 1; // error - cannot modify argument
}
task main()
{
int x = 5;
foo(5); // ok
foo(4*5); // expression is still constant
foo(x); // x is not a constant but is okay
}

The third type, arg_type &, passes arguments by reference rather than by value. This allows the called function to modify the value and have those changes be available in the calling function after the called function returns. However, only variables may be used when calling a function using arg_type & arguments:

void foo(int &x)
{
x = 2;
}
task main()
{
int y = 1; // y is equal to 1
foo(y); // y is now equal to 2
foo(2); // error - only variables allowed
}

The fourth type, const arg_type &, is interesting. It is also passed by reference, but with the restriction that the called function is not allowed to modify the value. Because of this restriction, the compiler is able to pass anything, not just variables, to functions using this type of argument. Currently, passing an argument by reference in SPC is not as optimal as it is in C. A copy of the argument is still made but the compiler will enforce the restriction that the value may not be modified inside the called function.

Functions must be invoked with the correct number and type of arguments. The code example below shows several different legal and illegal calls to function foo.

void foo(int bar, const int baz)
{
// do something here...
}
task main()
{
int x; // declare variable x
foo(1, 2); // ok
foo(x, 2); // ok
foo(2); // error - wrong number of arguments!
}