I have a few functions that return void
. I made pointers to these functions and wanted to have an array of these functions:
Why does this code work:
#include <cstdio>
using std::puts;
void tell() {
puts("hi");
};
void slap() {
puts("goodbye");
}
int main(int argc, char *argv[])
{
void (*tp)() = tell;
void (*sp)() = slap;
void(*funcs[])() = {tp, sp};
for (auto point:funcs) {
point();
}
return 0;
}
When I try this code with out specifying a pointer in funcs
(i.e. void(funcs[])() = {tp, sp};
I get " error: 'funcs' declared as array of functions of type 'void ()' "
Which is exactly what they are - so why is that an error?
I also don't get the syntax, wouldn't the ()
at the end of void(*funcs[])()
indicate actually calling a function?
An array can be created using all data types such as int, char, float, double etc. But creating an array by using the void data type is not possible.
Array Functions in C is a type of data structure that holds multiple elements of the same data type. The size of an array is fixed and the elements are collected in a sequential manner. There can be different dimensions of arrays and C programming does not limit the number of dimensions in an Array.
To create an array, define the data type (like int ) and specify the name of the array followed by square brackets []. To insert values to it, use a comma-separated list, inside curly braces: int myNumbers[] = {25, 50, 75, 100};
Void functions, also called nonvalue-returning functions, are used just like value-returning functions except void return types do not return a value when the function is executed. The void function accomplishes its task and then returns control to the caller. The void function call is a stand-alone statement.
C++ Standard 8.3.5/10 says:
There shall be no arrays of functions, although there can be arrays of pointers to functions.
The declaration of "funcs
" must be read using the "spiral rule":
funcs[]
: funcs
is an array
*funcs[]
: funcs
is an array of pointers
(*funcs[])()
: funcs
is an array of pointers to functions with no parameters
void (*funcs[])()
: funcs
is an array of pointers to functions with no parameters returning void
.
Well you can declare it explicitly like this:
void (*actions[5])();
But this is nearly unreadable.
To make it more readable use a typedef.
typedef void(*Action)(); // Action is the typename for a pointer
// to a function return null and taking
// no parameters.
Action actions[5]; // An array of 5 Action objects.
Or for your purposes:
int main()
{
Action actions[] = {&tell, &slap};
}
Without the asterisk, void (funcs[])()
declares an array of functions rather than array of pointers to functions. The latter is allowed in the C++ grammar while the former is not.
[dcl.array]/p1:
T
is called the array element type; this type shall not be a reference type, the (possibly cv-qualified) typevoid
, a function type or an abstract class type.
The contents of the initializer-list ({tp, sp}
) are functions but they are converted to pointers via the function-to-pointer conversion:
[conv.func]/p1
An lvalue of function type
T
can be converted to a prvalue of type “pointer toT
.” The result is a pointer to the function.
Note that C++ also doesn't allow an array of references.
I also don't get the syntax, wouldn't the
()
at the end ofvoid(*funcs[])()
indicate actually calling a function?
No, this is a declaration of an array type. The ()
is part of the construction of the type which specifies the argument list of the function. The entire type indicates "an array of pointers to functions which take zero arguments (()
) and return void
". It may become clearer with the use of a type alias:
using void_f = void (*)();
void_f funcs[] = {tp, sp};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With