Reputation: 13
I'm rather new at C, but what does this syntax mean?
typedef Value (*NativeFn)(int argCount, Value* args);
From what I understand, "Value" is used here to define the type of the new name.
The part I don't understand is (*NativeFn)(int argCount, Value* args);
, what does this part mean?
Upvotes: 0
Views: 206
Reputation: 1432
Well,
typedef (*NativeFn)(int argCount, Value* args)
means
NativeFn
is a function type(can also be called "a pointer to function" or "function pointer")
that returns Value
and takes a int
and a Value *
as arguments.
If you've troubling undertsanding why and how should we use it, then read the code below, specially the comments, it'll be clear to you, what (*NativeFn)(int argCount, Value* args)
means and how to use it:
#include <stdio.h>
// note: "Value" is a type declared earlier
// for discussions sake we're declaring our own Value type
typedef struct __value {
int x, y;
} Value;
// now, the following tells us that:
// "NativeFn" is some function type that returns "Value"
typedef Value (*NativeFn)(int argCount, Value* args);
// okay, see how to use "NativeFn"
// for use "NativeFn" we've to declare some function first
// which takes two arguments same as "NativeFn" and return "Value"
Value someFun(int argCount, Value* args) {
// do something argCount and args
// at last it should return some "Value" type
Value v = {2, 3};
return v;
}
int main() {
// now its time to use "NativeFn"
NativeFn fun;
fun = someFun; // notice we can use fun as a variable and assign a
// function to it, which must take arguments same as "NativeFn" and returns "Value" type
Value input = {10, 12};
Value output = fun(1, &input); // note, we're calling "fun", not "someFun"
// it'll output 2, 3, cause we're returning Value v = {2, 3} from "someFun"
printf("(x, y): %d, %d\n", output.x, output.y);
return 0;
}
If you've any question, ask me in the comment...
Upvotes: 0
Reputation: 263307
Others have correctly said that this:
typedef Value (*NativeFn)(int argCount, Value* args);
creates a typedef name NativeFn
for a pointer-to-function type.
The syntax of typedef
, like the syntax of C declarations in general, can be confusing. The typedef
feature was actually added to the language after the declaration syntax had been established, and it had to be added without breaking anything else. The solution was to treat typedef
syntactically like a storage class specifier (though it isn't one semantically). The storage class specifiers other than typedef
are extern
, static
, _Thread_local
, auto
, and register
.
Which means that you can understand a typedef
declaration by replacing the keyword typedef
by, for example, static
. Where a static
declaration declares an object (or function) of a certain type, a corresponding typedef
declaration creates a type definition with the same name and type. So this:
static int foo;
creates an object foo
of type int
(with static storage duration), while this:
typedef int foo;
creates a type name foo
that's an alias for type int
.
So if your declaration had been:
static Value (*NativeFn)(int argCount, Value* args);
it would have defined NativeFn
as a pointer-to-function object (with the function returning a result of type Value
). Replacing static
by typedef
means that NativeFn
is a type name that refers to that same pointer-to-function type.
It's also important to remember that typedef
does not create a new type. It creates a new name for an existing type.
Upvotes: 1
Reputation: 123468
The typedef
facility is used to create aliases for types. For example,
typedef int *iptr;
creates the name iptr
as a synonym for the type int *
, so you could declare pointers using
iptr p, q;
instead of writing
int *p, *q;
C declaration syntax is a bit more complicated than most people realize, especially where pointers are involved. The basic rules are:
T *p; // p is a pointer to T
T *a[N]; // a is an array of pointer to T
T *f(); // f is a function returning pointer to T
T (*a)[N]; // a is a pointer to an array of T
T (*f)(); // f is a pointer to a function returning T
T const *p; // p is a pointer to const T
const T *p; // same as above
T * const p; // p is a const pointer to T
Things can get arbitrarily complicated - you can have arrays of pointers to functions:
T (*a[N])();
or functions returning pointers to arrays:
T (*f())[N];
or even worse atrocities. Function pointer declarations get uglier when there are parameters in the mix; fortunately, you only need to list the parameter types in a declaration, not the names:
typedef Value (*NativeFn)(int, Value*);
makes things a little easier to follow.
That declaration creates NativeFn
as a synonym for the type "pointer to function taking an int
and Value *
and returning Value
".
Suppose you have a function defined as
Value foo( int argcCount, Value *args )
{
Value result;
...
return result;
}
If you want to create a pointer to this function named fptr
, you'd normally declare it as
Value (*fptr)(int, Value *) = foo;
However, the typedef
declaration above allows you to write
NativeFn fptr = foo;
Having said all that, use typedef
sparingly. The problem is that while it can create an easier-to-read ways of declaring some items, it also hides some potentially useful information. For example, despite the iptr
example above, it's best to not hide pointers behind typedefs - if someone needs to use the unary *
operator on p
or q
in order to use them properly, than that information needs to be in the declaration of those items. If someone ever needs to call the thing fptr
points to, then they need to know what the return type is, the number and types of parameters, etc., but all that information is missing in the declaration that uses the typedef name.
Upvotes: 0
Reputation: 310980
Consider such a record
Value (int argCount, Value* args)
It denotes a function type that has the return type Value
and two parameters of the type int
and Value *
.
The identifier Value
is declared somewhere else and can for example be an alias for a type.
To introduce an alias for a pointer type to the function type you can write
typedef Value (*NativeFn)(int argCount, Value* args);
So if you have a function as for example
Value some_function(int argCount, Value* args);
then you can declare a pointer to this function using the typedef alias definition the following way
NativeFn pointer_to_some_function = some_function;
Upvotes: 0