Typedef function pointer? - c++

I'm learning how to dynamically load DLL's but what I don't understand is this line
typedef void (*FunctionFunc)();
I have a few questions. If someone is able to answer them I would be grateful.
Why is typedef used?
The syntax looks odd; after void should there not be a function name or something? It looks like an anonymous function.
Is a function pointer created to store the memory address of a function?
So I'm confused at the moment; can you clarify things for me?

typedef is a language construct that associates a name to a type.
You use it the same way you would use the original type, for instance
typedef int myinteger;
typedef char *mystring;
typedef void (*myfunc)();
using them like
myinteger i; // is equivalent to int i;
mystring s; // is the same as char *s;
myfunc f; // compile equally as void (*f)();
As you can see, you could just replace the typedefed name with its definition given above.
The difficulty lies in the pointer to functions syntax and readability in C and C++, and the typedef can improve the readability of such declarations. However, the syntax is appropriate, since functions - unlike other simpler types - may have a return value and parameters, thus the sometimes lengthy and complex declaration of a pointer to function.
The readability may start to be really tricky with pointers to functions arrays, and some other even more indirect flavors.
To answer your three questions
Why is typedef used?
To ease the reading of the code - especially for pointers to functions, or structure names.
The syntax looks odd (in the pointer to function declaration)
That syntax is not obvious to read, at least when beginning. Using a typedef declaration instead eases the reading
Is a function pointer created to store the memory address of a function?
Yes, a function pointer stores the address of a function. This has nothing to do with the typedef construct which only ease the writing/reading of a program ; the compiler just expands the typedef definition before compiling the actual code.
Example:
typedef int (*t_somefunc)(int,int);
int product(int u, int v) {
return u*v;
}
t_somefunc afunc = &product;
...
int x2 = (*afunc)(123, 456); // call product() to calculate 123*456

typedef is used to alias types; in this case you're aliasing FunctionFunc to void(*)().
Indeed the syntax does look odd, have a look at this:
typedef void (*FunctionFunc) ( );
// ^ ^ ^
// return type type name arguments
No, this simply tells the compiler that the FunctionFunc type will be a function pointer, it doesn't define one, like this:
FunctionFunc x;
void doSomething() { printf("Hello there\n"); }
x = &doSomething;
x(); //prints "Hello there"

Without the typedef word, in C++ the declaration would declare a variable FunctionFunc of type pointer to function of no arguments, returning void.
With the typedef it instead defines FunctionFunc as a name for that type.

If you can use C++11 you may want to use std::function and using keyword.
using FunctionFunc = std::function<void(int arg1, std::string arg2)>;

#include <stdio.h>
#include <math.h>
/*
To define a new type name with typedef, follow these steps:
1. Write the statement as if a variable of the desired type were being declared.
2. Where the name of the declared variable would normally appear, substitute the new type name.
3. In front of everything, place the keyword typedef.
*/
// typedef a primitive data type
typedef double distance;
// typedef struct
typedef struct{
int x;
int y;
} point;
//typedef an array
typedef point points[100];
points ps = {0}; // ps is an array of 100 point
// typedef a function
typedef distance (*distanceFun_p)(point,point) ; // TYPE_DEF distanceFun_p TO BE int (*distanceFun_p)(point,point)
// prototype a function
distance findDistance(point, point);
int main(int argc, char const *argv[])
{
// delcare a function pointer
distanceFun_p func_p;
// initialize the function pointer with a function address
func_p = findDistance;
// initialize two point variables
point p1 = {0,0} , p2 = {1,1};
// call the function through the pointer
distance d = func_p(p1,p2);
printf("the distance is %f\n", d );
return 0;
}
distance findDistance(point p1, point p2)
{
distance xdiff = p1.x - p2.x;
distance ydiff = p1.y - p2.y;
return sqrt( (xdiff * xdiff) + (ydiff * ydiff) );
}

For general case of syntax you can look at annex A of the ANSI C standard.
In the Backus-Naur form from there, you can see that typedef has the type storage-class-specifier.
In the type declaration-specifiers you can see that you can mix many specifier types, the order of which does not matter.
For example, it is correct to say,
long typedef long a;
to define the type a as an alias for long long. So , to understand the typedef on the exhaustive use you need to consult some backus-naur form that defines the syntax (there are many correct grammars for ANSI C, not only that of ISO).
When you use typedef to define an alias for a function type you need to put the alias in the same place where you put the identifier of the function. In your case you define the type FunctionFunc as an alias for a pointer to function whose type checking is disabled at call and returning nothing.

Related

Declaration of a function pointer's typedef in C++

I understand that similar questions with answers have been asked before. I already understand the concept of a function pointer and the meaning of its declaration. Following is my sample code of a function's pointer, where I assign the function pointer fp_GetBiggerElement to point to the function GetBiggerElement
#include <iostream>
typedef int (*fp_GetBiggerElement) (int, int);
// ^ ^ ^
// return type type name arguments
using namespace std;
int GetBiggerElement(int arg1, int arg2)
{
int bigger = arg1 > arg2 ? arg1 : arg2;
return bigger;
}
int main()
{
fp_GetBiggerElement funcPtr = GetBiggerElement;
int valueReturned = funcPtr(10, 20);
cout << valueReturned << endl;
return 0;
}
What I understand is, typedef means to assing a new definition for a type. Usually, the typedef statement needs two-parts(or say two-arguments)
first part is the type which needs a new alias
second part is a new alias name
typedef unsigned int UnsignedInt;
// ^ ^
// (original type) (Alias)
for example, in the code above, the first part is unsigned int and the second part is UnsignedInt
typedef char * CharPtr;
// ^ ^
// (original type) (Alias)
similarly, in the second example above, the first part is char* and the second part is CharPtr
QUESTION: I am confused with the FORMAT of the typedef statement for a function pointer. In the statement typedef int(*fp_GetBiggerElement)(int, int);, the typical two-arguments format for typedef is not followed then, how is it working?
UPDATE: I am aware that C++11 offers another way of declaring function pointer i.e. (by using statment). In this question, I am only interested to understand the syntax of typedef statement for a fucntion pointer.
I think the best idea to think about typedef syntax is like declaring variable of type you want to typedef. For example:
char *CharPtr;// declare CharPtr to be variable of type char*
typedef char *CharPtr_t;// declare CharPtr_t to be alias of type char*
Similarly with function pointers:
int (*fp) (int, int);// declare fp as pointer to int(int, int)
typedef int (*fp_t)(int, int);// declare fp_t to be alias of pointer to int(int, int)
Btw, in C++11 and further you get not-so-confusing (and more powerful) alternative to typedef - using. You should be using (pun intended) it instead. Just look:
using fp = int (*)(int, int);// declare fp_t to be alias of pointer to int(int, int)
typedef uses the same syntax as a variable declaration, but declares a type name rather than a variable name.
The parts are "intermingled" in a somewhat peculiar (some would call it "wtf?") way - a variable declaration has the same form as its use, which simplifies the parser and enables reusing code in the compiler.
It makes more sense if you read in a more "old-school" way:
int *p;
"*p is an int"
(Equivalent translation: "p is a pointer to int")
int *p, x;
"*p and x are both ints"
("p is a pointer to int, and x is an int")
int (*q)[3];
"*q is an array of three ints", or "(*q)[x] is an int"
("q is a pointer to an array of three ints")
int (*fp)(int,int);
"*fp is a function that takes two ints and returns an int"
("fp is a pointer to a function that takes two ints and returns an int")
int (*(*foo)())[3];
"*(*foo)() is an array of three ints" (alternatively, "(*(*foo)())[x] is an int) - or, in other words,
"(*foo)() is a pointer to an array of three ints" - or, in other words,
"foo is a pointer to a function that takes no arguments and returns a pointer to an array of three ints"
A slightly unreadable effect of this is that
int *p, x, (*q)[3], (*fp)(int,int), (*(*foo)())[3];
declares all of the above at once.
That's just the syntax for function pointers.
You would see the same thing if you just declare a variable.
int foo; // Normal
int (*bar)(int, int); // bar is of type int(*)(int,int)
Personally i prefer to use using = ... which in my opinion is more clear.
using fp_GetBiggerElement = int (*)(int,int);
This syntax comes from the C-way of reading variables.
Ever wondered why we need an asterisk, for every pointer we want to declare in a single expression?
int *p1, *p2, p3; // p3 is not a pointer
C++ people generally tend to see a variable having a specific type, which can be a pointer (in other words, they see the pointer characteristics as property of the type). That's why they usually prefer writing
int* p1; // notice asterisk grouped with type
C people rather read as: I have a variable p1, and if I dereference it, I get type int (so p1 being a pointer is deduced information, i. e. they see the pointer characteristics rather as property of the variable; and that's why they rather group the asterisk to the name: int *p1;).
Pretty similar for function pointers:
int (*fp) (int, int);
I have a variable fp, and if I dereference it, I get int (int, int). Same pattern then for the typedef. On the other hand, the (new) C++ way for defining an alias reflects much better the C++ way of thinking:
using fp = int (*)(int, int);
I have a variable, and it's type is a pointer (to whatever) right from the start – well, not fully consistently, though: With C++ way of thinking, function pointers might rather look like int(int, int)* or maybe requiring parentheses (int(int, int))*, but OK, that's not the way it is (wanting to stay compatible with C being reason for).
typedef declarations are similar to simple declarations but instead of declaring an identifier of a derclarator as an identifier of an object or a function they declare an identifier of a declarator as an alias for the specified type.
Consider the following examples of simple declarations
int x;
unsigned int a[10][20];
int unsigned ( *p )[10][20];
void ( *f )( int, int );
double h( double );
They declare several objects and the function h.
Now place in these declarations decl-specifier typedef (in any order relative to other decl-specifiers) and you will get that the declared identifiers become aliases of types.
typedef int x;
unsigned typedef int a[10][20];
int unsigned typedef ( *p )[10][20];
void typedef ( *f )( int, int );
typedef double h( double );
That is x is an alias of the type int. a is an alias for the type unsigned int [10][20]. p is an alias for the pointer type unsigned int ( * )[10][20]. f is an alias for the function pointer void ( * )( int, int ). And h in an alias for the function type double( double ).

Unusual variable declaration in C++ [duplicate]

For example a declaration such as that:
int (x) = 0;
Or even that:
int (((x))) = 0;
I stumbled upon this because in my code I happened to have a fragment similar to the following one:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Obviously I wanted to construct object C which then would do something useful in its destructor. However as it happens compiler treats C (y); as a declaration of variable y with type C and thus it prints an error about y redefinition. Interesting thing is that if I write it as C (y).f () or as something like C (static_cast<B*> (y)) it will compile as intended. The best modern workaround is to use {} in constructor call, of course.
So as I figured out after that, it's possible to declare variables like int (x) = 0; or even int (((x))) = 0; but I've never seen anyone actually using declarations like this. So I'm interested -what's the purpose of such possibility because for now I see that it only creates the case similar to the notorious "most vexing parse" and doesn't add anything useful?
Grouping.
As a particular example, consider that you can declare a variable of function type such as
int f(int);
Now, how would you declare a pointer to such a thing?
int *f(int);
Nope, doesn't work! This is interpreted as a function returning int*. You need to add in the parentheses to make it parse the right way:
int (*f)(int);
The same deal with arrays:
int *x[5]; // array of five int*
int (*x)[5]; // pointer to array of five int
There's generally allowed to use parentheses in such declarations because the declaration, from the syntactical point of view looks always like this:
<front type> <specification>;
For example, in the following declaration:
int* p[2];
The "front type" is int (not int*) and the "specification" is * p[2].
The rule is that you can use any number of parentheses as needed in the "specification" part because they are sometimes inevitable to disambiguate. For example:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints
The pointer to an array is a rare case, however the same situation you have with a pointer to function:
int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int
This is the direct answer to your question. If your question is about the statement like C(y), then:
Put parentheses around the whole expression - (C(y)) and you'll get what you wanted
This statement does nothing but creating a temporary object, which ceases to living after this instruction ends (I hope this is what you intended to do).

Why is the constructor not called when assigning a functor to a std::function? [duplicate]

For example a declaration such as that:
int (x) = 0;
Or even that:
int (((x))) = 0;
I stumbled upon this because in my code I happened to have a fragment similar to the following one:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Obviously I wanted to construct object C which then would do something useful in its destructor. However as it happens compiler treats C (y); as a declaration of variable y with type C and thus it prints an error about y redefinition. Interesting thing is that if I write it as C (y).f () or as something like C (static_cast<B*> (y)) it will compile as intended. The best modern workaround is to use {} in constructor call, of course.
So as I figured out after that, it's possible to declare variables like int (x) = 0; or even int (((x))) = 0; but I've never seen anyone actually using declarations like this. So I'm interested -what's the purpose of such possibility because for now I see that it only creates the case similar to the notorious "most vexing parse" and doesn't add anything useful?
Grouping.
As a particular example, consider that you can declare a variable of function type such as
int f(int);
Now, how would you declare a pointer to such a thing?
int *f(int);
Nope, doesn't work! This is interpreted as a function returning int*. You need to add in the parentheses to make it parse the right way:
int (*f)(int);
The same deal with arrays:
int *x[5]; // array of five int*
int (*x)[5]; // pointer to array of five int
There's generally allowed to use parentheses in such declarations because the declaration, from the syntactical point of view looks always like this:
<front type> <specification>;
For example, in the following declaration:
int* p[2];
The "front type" is int (not int*) and the "specification" is * p[2].
The rule is that you can use any number of parentheses as needed in the "specification" part because they are sometimes inevitable to disambiguate. For example:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints
The pointer to an array is a rare case, however the same situation you have with a pointer to function:
int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int
This is the direct answer to your question. If your question is about the statement like C(y), then:
Put parentheses around the whole expression - (C(y)) and you'll get what you wanted
This statement does nothing but creating a temporary object, which ceases to living after this instruction ends (I hope this is what you intended to do).

Why does C++ allow us to surround the variable name in parentheses when declaring a variable?

For example a declaration such as that:
int (x) = 0;
Or even that:
int (((x))) = 0;
I stumbled upon this because in my code I happened to have a fragment similar to the following one:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Obviously I wanted to construct object C which then would do something useful in its destructor. However as it happens compiler treats C (y); as a declaration of variable y with type C and thus it prints an error about y redefinition. Interesting thing is that if I write it as C (y).f () or as something like C (static_cast<B*> (y)) it will compile as intended. The best modern workaround is to use {} in constructor call, of course.
So as I figured out after that, it's possible to declare variables like int (x) = 0; or even int (((x))) = 0; but I've never seen anyone actually using declarations like this. So I'm interested -what's the purpose of such possibility because for now I see that it only creates the case similar to the notorious "most vexing parse" and doesn't add anything useful?
Grouping.
As a particular example, consider that you can declare a variable of function type such as
int f(int);
Now, how would you declare a pointer to such a thing?
int *f(int);
Nope, doesn't work! This is interpreted as a function returning int*. You need to add in the parentheses to make it parse the right way:
int (*f)(int);
The same deal with arrays:
int *x[5]; // array of five int*
int (*x)[5]; // pointer to array of five int
There's generally allowed to use parentheses in such declarations because the declaration, from the syntactical point of view looks always like this:
<front type> <specification>;
For example, in the following declaration:
int* p[2];
The "front type" is int (not int*) and the "specification" is * p[2].
The rule is that you can use any number of parentheses as needed in the "specification" part because they are sometimes inevitable to disambiguate. For example:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints
The pointer to an array is a rare case, however the same situation you have with a pointer to function:
int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int
This is the direct answer to your question. If your question is about the statement like C(y), then:
Put parentheses around the whole expression - (C(y)) and you'll get what you wanted
This statement does nothing but creating a temporary object, which ceases to living after this instruction ends (I hope this is what you intended to do).

What does this typedef definition mean?

I have seen the following (C++):
typedef n *(m)(const n*, const n*);
What does it mean and how can it be used?
I understand this:
typedef n (*myFunctP)(const n*, const n*);
but what is the difference to the typedef above?
(Hope this is no duplicate, did not find something similar...)
I asked geordi to win me some rep:
<tomalak> << TYPE_DESC<m>; struct n {}; typedef n *(m)(const n*, const n*);
<geordi> function taking 2 pointers to constant ns and returning a pointer to a n
C type declaration syntax is horrible and it does become particularly apparent when you start doing complex declarations like this. Notice how the return type and arguments are written around the m, not the n, which is totally backwards to intuition since it's m that you're creating.
Your second example is:
<tomalak> << TYPE_DESC<m>; struct n {}; typedef n (*m)(const n*, const n*);
<geordi> pointer to a function taking 2 pointers to constant ns and returning a n
By moving the *, you are no longer applying it to the function type's return type, but to the function type itself.
In C++11, unless you have a desperate need for your calls to be hyper-efficient, please stick to the following, for the love of Cthulhu! :-)
typedef std::function<n*(const n*, const n*)> m;
If you wish to stick to function pointers then you can:
using m = n*(const n*, const n*);
Prior to that you can use boost::function or learn the horrific C declarator rules. It is true that you should know them; it's just that hopefully you won't have to use them too often.
The first typedef creates an alias for a function which takes 2 parameters and returns a pointer-to-n.
The second typedef creates an alias for a pointer-to-function which takes 2 parameters and returns an n by value.
In the first case the typedef defines an alias for a function type that has two parameters of type const n *and return type n *
In the second case instead of the function type there is a declaration of a function pointer having return type n.
In the first case you could write also for example
typedef n * ( (m)(const n*, const n*) );
It is equivalent to your typedef.
As for the usage you can use it as a function declaration. For exmaple
m MyFunc;
Another example
struct A
{
typedef int n;
typedef n ( Operation )( n, n ) const;
Operation Add;
Operation Subtract;
Operation Division;
Operation Multiply;
};
// and below the function definitions