One question about function definition in C++ - c++

I'm reading some material about function pointer in C++, and come across one function definition which I do not understand.
Standard function definition have the form:
type name (param...)
But the following definition seems a little strange to me. Can anyone explain it to me ?
Thanks.
float (*GetPtr1(const char opCode)) (float, float)<br>
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}
Note: Plus and Minus are two functions with param (float, float) and return a float.

GetPtr1 is a function that takes an opcode char and returns a pointer to a function. The function it returns takes two floats and returns a float.
A lot of times it's easier to read if you do something like this:
typedef float (*FloatOperationFuncPtr) (float, float);
FloatOperationFuncPtr GetPtr1(const char opCode)
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}

The rule for reading hairy declarations is to start with the leftmost identifier and work your way out, remembering that () and [] bind before * (i.e., *a[] is an array of pointers, (*a)[] is a pointer to an array, *f() is a function returning a pointer, and (*f)() is a pointer to a function):
GetPtr1 -- GetPtr1
GetPtr1( ) -- is a function
GetPtr1( opCode) -- taking a single parameter named opCode
GetPtr1(const char opCode) -- of type const char
*GetPtr1(const char opCode) -- and returning a pointer
(*GetPtr1(const char opCode)) ( ) -- to a function
(*GetPtr1(const char opCode)) (float, float) -- taking two parameters of type float
float (*GetPtr1(const char opCode)) (float, float) -- and returning float
So, if opCode is equal to '+', GetPtr1 will return a pointer to the function Plus, and if it's '-', it will return a pointer to the function Minus.
C and C++ declaration syntax is expression-centric (much as Bjarne would like to pretend otherwise); the form of the declaration should match the form of the expression as it would be used in the code.
If we have a function f that returns a pointer to int and we want to access the value being pointed to, we execute the function and dereference the result:
x = *f();
The type of the expression *f() is int, so the declaration/definition for the function is
int *f() { ... }
Now suppose we have a function f1 that returns a pointer to the function f defined above, and we want to access that integer value by calling f1. We need to call f1, derefence the result (which is the function f), and execute it, and then dereference that result (since f returns a pointer):
x = *(*f1())(); // *f1() == f, so (*f1())() == f() and *(*f1())() == *f()
The type of the expression *(*f1())() is int, so the decaration/definition for f1 needs to be
int *(*f1())() { return f; }

Always nice to know about http://cdecl.org for such situations. Be aware that it only works if you remove the parameter names. This is what you get for float(*GetPtr1(const char ))(float, float):
declare GetPtr1 as function (const char) returning pointer to function (float, float) returning float

It's a function that takes a const char and returns a pointer to a function that takes float, float and returns a float.

That means a function which takes a character and returns a pointer to a function that takes two floats and returns a float.

GetPtr1 is a function that takes two float as input parameters and returns a pointer to a function. This is much more clear:
typedef float(*Func)(float, float);
Func GetPtr1(const char opCode)
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}

Related

What does the value from dereferencing a function pointer means

#include <iostream>
void PrintTheValue(int(*func)(int a));
int main(int argc, char **argv) {
PrintTheValue([](int a) {return a; });
return 0;
}
void PrintTheValue(int(*func)(int a)) {
std::cout << *func << std::endl;
}
In my concept of understanding the func, it would be a pointer to an int passed by value. But in this case I'm passing a lambda which doesn't seem to be called anywhere. (So there isn't any value at all?)
When I run this, it doesn't break the program, but instead printed 00EE6F80.
What does this address mean? I have no idea how to interpret it.
In my concept of understanding the func, it would be a pointer to an int passed by value.
func is a pointer to function, which takes an int and returns int.
But in this case I'm passing a lambda which doesn't seem to be called anywhere.
You're passing a lambda without capturing, which could convert to pointer to function implicitly. In PrintTheValue, *func, i.e dereference on the pointer results in a reference to function, and for being passed to operator<< of std::cout, it converts to function pointer again, then converts to bool with value true (as a non-null pointer), then you should get the result 1 (or true with the usage of std::boolalpha). If you want to call on func you could func(42) (or (*func)(42)).
A lambda is an unnamed function object of the closure type.
The crucial part for this case, this class does not overload the operator<<.
When you dereference the passed lambda in *func, there is no overload for operator<<, so it converts to nearest acceptable result which is bool (at first it reverts to a regular pointer).
The documentation:
Dereferencing a function pointer yields the lvalue identifying the pointed-to function
int f();
int (*p)() = f; // pointer p is pointing to f
(*p)(); // function f invoked through the function lvalue
// But no sense in *p
It should print 1 (since non-null pointer), which it does for me (g++). The language does allow us to do so, but there's no sense in dereferencing a pointer to function without calling the function. All the peculiarities of the function pointers are due to that they have one reasonable usage, so anything you do with them will support that usage - #Pete Becker
For more on Function Pointers check here, it will aid.

I cant understand an expression of type casting

I got a program which has following expression but I cannot undersrand the meaning.
unsigned (*getid)(const char*);
Is this declaration of getid ?
I am confused cause i met such expression for the first time and I couldnt come up with the keyword to search.
Thank you very much in advance.
This isn't a type-cast.
unsigned (*getid)(const char*); declares a pointer to a function that takes a const char* and returns an unsigned [int] and calls this getid.
Further reading:
Function Pointers
It is a function pointer - getid. - with a signature demonstrated beow
e.g.
unsigned mygetid(const char *i) { return 0; }
getid = mygetid;
getid is declared to be a pointer to a function which takes a const char* as an argument and returns an unsigned. Without the parentheses, the declaration would be for a function named getid which returns an unsigned * -- i.e. pointer to an unsigned integer.
For more information, see Programs as Data: Function Pointers.
This is the declaration of a pointer to a function that returns an unsigned andtakes a char * as argument.
example:
// a couple of functions with the same prototypes
unsigned id_getter_1 (const char * name)
{
// ...
}
unsigned id_getter_2 (const char * name)
{
// ...
}
// a pointer to one of these functions
unsigned (*getid)(const char*);
// assigning the function to the pointer
if (ID_TYPE == 1)
getid = id_getter_1;
else
getid = id_getter_2;
// calling one of the functions through pointer
getid("xxx");
This is useful when you want a different code to be used depending on the circumstances. You select a variant of the code, and then use the pointer just as it it was a function name.
You might want to use typedef to make the code more readable:
// define a "pointer to getter function" type
typedef unsigned (* IdGetter) (const char * name);
// declare a "pointer to getter function"
IdGetter my_getter;
Is this declaration of getid ?
Yes it is. There is no casting here but this is a declaration of the pointer to a function that takes const char* as argument and returns unsigned [int] and this pointer is called getid. You can always use this site to find out meanings of such declarations.
keyword to search is: pointer to a function, declaration

Why are both these function pointers legal in C/C++?

I have these two test functions:
int apply_a(int (*fun)(int, int), int m, int n) {
return (*fun)(m,n);
}
int apply_b(int (*fun)(int, int), int m, int n) {
return fun(m,n);
}
they appear to return something different, so why do both of them yield the same result?
int add(int a, int b) {return a + b;}
int res_a = apply_a(add, 2, 3); // returns 5
int res_b = apply_b(add, 2, 3); // returns 5
I would've assumed that one of them would return the pointer address or the pointer itself; rather than the value stored on the pointer...
So why is it doing this?
Because C++ offers syntactic sugar when it comes to handling the address of non-member functions and using pointers to them.
One can get address of such function:
int someFunc(int);
with either:
int (* someFuncPtr)(int) = someFunc;
or:
int (* someFuncPtr)(int) = &someFunc;
There is also syntactic sugar for using such pointer, either call pointed-to function with:
(*someFuncPtr)(5);
or with simplified syntax:
someFuncPtr(5);
(*fun)(m,n) is the same as fun(m,n) due to rules in C and C++ that convert functions to pointers to functions.
In C 2011, the rule is clause 6.3.2.1 4: “A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, a function designator with type “function returning type” is converted to an expression that has type “pointer to function returning type”. In C++, the rule is clause 4.3.
Note that a function designator is not merely an identifier that names a function. It could be an identifier, or it could be another expression. For example, if foo is the name of a function, it is automatically converted to a pointer to a function by the above. Then, since foo is a pointer to the function, *foo is the function. This means you can write:
(*fun)(m,n)
The result is that fun is automatically converted to a pointer, then * evaluates to the function, then *fun is converted back to a pointer, then the function is called. You can continue this and write:
(**************fun)(m,n)
This is the same as fun(m,n). Each * produces the function again, but the compiler automatically converts it back to a pointer. You can continue this battle forever, but the compiler will always win.
In fact, these all have the same effect:
(&fun)(m,n)
( fun)(m,n)
(*fun)(m,n)
It is because you are not returning memory addresses of these values.
Calling a function with pointer does not change it's value it's still calling the function. What you can do is return a value to a variable and then get it's memory address such as:
int result = fun(m,n);
cout << "the result " << result << " pointing at " << &result << endl;
In C and C++ name of functions are also the pointers to the function code. As any pointer you can dereference them using *, which in case of function pointers mean invocation of the function when in addition to dereferencing you use also paranthesis after them, like in your apply_a case. But also valid invocation of C and C++ function is calling them simply by their name, which is apply_b case.

Pointers to Functions (C++)

I am studying a C++ tutorial. I can't understand this example on Pointers to Functions.
Here it is:-
// pointer to functions
#include <iostream>
using namespace std;
int addition (int a, int b)
{ return (a+b); }
int subtraction (int a, int b)
{ return (a-b); }
int operation (int x, int y, int (*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
return (g);
}
int main ()
{
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n;
return 0;
}
The lines "m = operation (7, 5, addition);" and "n = operation (20, m, minus);" are treated the same way, but while minus has been declared as a pointer to function, addition hasn't. So, how did they both work the same way?
Using a function name as an argument parameter in a function call, or on the right-hand side of the assignment operator in C/C++, causes a conversion to a function pointer to the original function.
So for instance if you have a function like
void my_function(int a, int b);
If you use the identifier my_function on the right-hand side of the assignment operator like this:
void (*my_function_ptr)(int, int) = my_function;
Then my_function implicitly converts from a function object to a function pointer of type void (*)(int, int), initializing the identifier my_function_ptr so that it points to my_function. The same situation would also occur when passing my_function to another function like:
void another_function(int, void (*)(int, int));
another_function(5, my_function);
In the call to another_function(), the identifier my_function is again converted to a pointer to the original function.
Finally, keep in mind this only occurs if you simply pass the identifier name to a function argument, or put it on the right-hand side of the assignment operator. Adding a function call using the () symbols and an optional argument list (i.e., my_function(5, 6)) will evaluate the function, not cause a conversion to a function pointer.
The type of addition is int (&)(int,int) which can decay into a pointer of type int (*)(int,int) which is same as that of operation function's third parameter. So you can pass addition as third argument to the function operation.
The type of subtraction is also the same as that of addition. In your code, the address of subtraction is first stored as local variable of the compatible type, and then that variable is passed as argument to operation function.
In case of addition, it's address is not stored as local variable, instead its passed as such to operation. Its initializing the function's third parameter directly with the function's address, without using any local variable.
A conversion from int (&)(int,int) to int (*)(int,int) occurs in both cases. Its just that with substration, the conversion occurs when initializing the local variable, and with addition, the conversion occurs when initializing the function parameter.
An analogy would be this:
void f(double a, double b) {}
int main()
{
double x = 100;//first store 100 in a local variable
f(x, 100); //pass the local variable as first arg,
//and pass 100 as second arg without using any local variable.
}
Note the type of 100 is int, so it first converts to double type, which is then stored as local variable x, which in turn is passed to the function f as first argument. And the second argument 100 is passed directly to the function, so even now it first converts to double and then it initializes b (the second parameter of the function).
Again, a conversion from int to double occurs in both cases. Its just that first argument conversion occurs when initializing the local variable x, and second argument conversion occurs when initializing the second parameter of the function.
name of the function in C is resolved to its address. So this works:
int (*minus)(int,int) = subtraction;
Both solutions work: the third argument of "operation" must be a function pointer.
Please note that the ampersand is optional:
m = operation (7, 5, &addition);
also works.
By passing "addition" to operation() you're effectively assigning it to "functocall". It's exactly the same as assigning "subtraction" to "minus". They work the same way because they are the same.
The real question is, why don't you need an ampersand (&) to take the function's address?
p.s. Apart from the gratuitous use of iostream, namespace and cout, this is actually a C tutorial. Right?
C++ provides implicit function-to-pointer conversion (see 4.3 in C++ 2003 standard). In your example, it is used both for assignment of subtraction to minus and for conversion of addition to the parameter type accepted by operation. So essentially both calls are done the same way, just in one case you explicitly created an intermediate variable of type pointer-to-function. And in both cases an optimizing compiler will simply pass the address of a corresponding function into operation.

Cryptic C++ "thing" (function pointer)

What is this syntax for in C++? Can someone point me to the technical term so I can see if I find anything in my text?
At first I thought it was a prototype but then the = and (*fn) threw me off...
Here is my example:
void (*fn) (int&,int&) = x;
It can be rewritten to
typedef void (*T) (int&, int&);
T fn = x;
The 2nd statement is obvious, which should have solved that = x; question. In the 1st statement, we make T as a synonym as the type void(*)(int&, int&), which means:
a pointer to a function ((*…))
returning void
and taking 2 arguments: int&, int&.
That is a function pointer to a function taking two int reference parameters, which returns nothing. The function pointer is called fn and is being assigned the value in x.
This declares and initializes a function pointer.
The name of the variable is fn, and it points to a function with the following signature:
void pointedToFunction(int&, int&)
The variable fn is initialized to the value contained in x.
The pointed-to function can be called using the following syntax:
int a;
int b;
(*fn)(a,b);
This is equivalent to
int a;
int b;
pointedToFunction(a,b);
Function pointer.
http://www.newty.de/fpt/intro.html#what
^ Okay source for a beginner. :-)
This is a pointer to a function that takes two references to ints and returns void.
That seems like a function pointer to a method that takes two integer references and does not return anything. The pointer will be named fn. You are assigning it to the address of x, which is hopefully a function that matches this description.
It's a function pointer to a function that takes 2 integers as arguments and returns void. x must be a function name.
It's a function pointer variable that gets initialized to the stuff to the right of =.
The function type could be written like this:
typedef void func_t(int&,int&);
The function pointer than would be:
typedef func_t *fn_t;
With these definitions the variable declaration would be much clearer:
fn_t fn = ...;
Wikipedia page with a few links on the subject: http://en.wikipedia.org/wiki/Function_pointer