Reputation: 1378
How can I use this defined type ?
typedef void (*(workers[2]))(char *, char *, int);
What I could understand, that I'll have workers
, which is an array
of two
pointers
, each one points to a void
, which accepts the mentioned arguments.
Is that correct ?
Trial #1
void worker1(char * x, char * y, int z) {
}
void worker2(char * x, char * y, int z) {
}
and then inside some another void, I did:
workers w;
w[0] = worker1;
w[1] = worker2;
Compiling, I get:
error: cannot convert `void (**)(char*, char*, int)' to `void (* (*)[2])(char*, char*, int)'
Upvotes: 1
Views: 91
Reputation: 14454
Suppose:
typedef void (*(workers[2]))(char *, char *, int);
workers my_workers;
The workers
is a type (really, an alias for a type). The my_workers
is an object of the workers
type.
The my_workers
is an array of two pointers, each pointing to a function. Each such function accepts the mentioned arguments and returns void
.
TRIAL
As your request, I have tried your code as follows.
#include <stdio.h>
typedef void (*(workers[2]))(char *, char *, int);
void worker1(char * x, char * y, int z) {
printf("1: [%s] [%s] [%d]\n", x, y, z);
}
void worker2(char * x, char * y, int z) {
printf("2: [%s] [%s] [%d]\n", x, y, z);
}
int main() {
char sa[] = "here";
char sb[] = "there";
char sc[] = "everywhere";
char sd[] = "nowhere";
workers w;
w[0] = worker1;
w[1] = worker2;
(w[0])(sa, sb, 50);
(w[1])(sc, sd, 70);
return 0;
}
Try that. For me, it compiles and runs with no warnings, no errors.
Upvotes: 1
Reputation: 123448
workers
is an alias for the type "2-element array of pointers to functions taking two char *
and an int
as arguments and returning void
".
Here's an example of what this beast might look like in practice.
void f0( char *foo, char *bar, int bletch )
{
// do something interesting with foo, bar, and bletch
}
void f1( char *foo, char *bar, int bletch )
{
// do something else interesting with foo, bar, and bletch
}
int main( void )
{
workers w = { f0, f1 }; // equivalent to void (*w[2])(char *, char *, int ) = { f0, f1 };
// call f0 through w:
w[0]( "blah", "blah", 1 );
// call f1 through w:
w[1]( "ugh", "blah", 2 );
...
}
The workers
typedef basically creates a shorter name for a complicated, hard-to-read type. In practice, it would probably be better to create a typedef for just the function type, then create an array of that:
typedef (*worker)(char *, char *, int );
worker w[2] = { f0, f1 };
The problem with a declaration like
workers w = { f0, f1 };
is that it's not immediately obvious that w
has an array type, so the initialization looks confusing. It also relies on the person using this type to know that it's an array type of a certain size. We call that a "leaky abstraction", and they lead to confusion and maintenance headaches.
You still have to know that each w[i]
is a function type that takes a certain number and type of arguments, so ideally that should be hidden behind an interface as well (i.e., you pass w[i]
to a function that knows how to call it, rather than calling it yourself).
Upvotes: 3