What is the need for function pointers? The standard answer for this seems to be callbacks, but why can't we just pass a function?
The book I was reading on C++ demonstrates passing a function as a parameter, and acknowledges that in actual fact the compiled turns this into a function pointer and passes that instead, because functions are not actual objects. It showed the equivalent code using function pointers, which was slightly more complex - if the code is equivalent, why bother to use a function pointer.
I presume there is a case when is simply isn't possible to pass the function, and one must pass a pointer instead? Can someone give me an example of this case, as it would help me understand why function pointers are useful.
Consider the following code:
#include <iostream>
using namespace std;
int add(int x) {
return ++x; //this is a copy, so it doesn't touch x
}
void runprint(int function(int x), int x) {
cout << function(x) << endl;
}
int main() {
runprint(add, 1);
return 0;
}
We are passing a function as a parameter, not a pointer. The function accepting the function (!), is not accepting a pointer.
TL; DR
"Function" and "pointer to function" is the same.
There is the concept of a pointer, and the syntax of its usage; it's not clear what you are asking about.
Concept
A pointer to a function may be different from the function itself (the difference is not useful in c++ - see below) in that a function may occupy much space - its code can be arbitrarily complex. Manipulating (e.g. copying or searching/modifying) the code of a function is rarely useful, so c/c++ don't support it at all. If you want to modify the code of a function, cast a pointer to char*, applying all the necessary precautions (I have never done it).
So if you are writing C, all you need is pointers to functions.
However...
Syntax
If you have a pointer p to a function, how do you want to call the function?
(*p)(18); // call the function with parameter 18
p(18); // the same, but looks better!
There is the slightly cleaner syntax not involving the * sign. To support it, the authors of c/c++ invented the concept of "decay" - when your code mentions "a function", the compiler silently "corrects" it to mean "a pointer to a function" instead (in almost all circumstances; excuse me for not detailing further). This is very similar to the "decay" of an array to a pointer mentioned by vsoftco.
So in your example
void runprint(int function(int x), int x) {
cout << function(x) << endl;
}
the "function" type is actually a "pointer to function" type. Indeed, if you try to "overload":
void runprint(int (*function)(int x), int x) {
cout << function(x) << endl;
}
the compiler will complain about two identical functions with identical set of parameters.
Also, when making a variable of a function / pointer-to-function type
runprint(add, 1);
it also doesn't matter:
runprint(&add, 1); // does exactly the same
P.S. When declaring a function that receives a callback, I have mostly seen (and used) the explicitly written pointer. It has only now occurred to me that it's inconsistent to rely on function-to-pointer decay when calling the callback, but not when declaring my code. So if the question is
why does everyone declare callbacks using a pointer-to-function syntax, when a function syntax would be sufficient?
I'd answer "a matter of habit".
function is considered a function pointer by g++:
$ cat fp.cpp
#include <typeinfo>
#include <iostream>
using namespace std;
int add(int x) {
return ++x; //this is a copy, so it doesn't touch x
}
void runprint(int function(int x), int x) {
cout << typeid(function).name() << endl;
int (*f)(int); // function pointer compatible with function argument
f = function;
cout << typeid(f).name() << endl;
cout << function(x) << endl;
}
int main() {
runprint(add, 1);
return 0;
}
$ g++ -Wall -std=c++11 -o fp fp.cpp
$ ./fp
PFiiE
PFiiE
2
Function pointer is a pointer that holds the address of the function.
Function pointer is to invoke the function even if the name of the function is unknown. This is practical in using different function at runtime.
Related
Consider the code
int add(int a, int b)
{
return a + b;
}
int main()
{
std::cout << (*add)(3, 2);
}
What is the point of dereferencing the function pointer ???
I can't think of such a use case where it would give an advantage ...
Why this function call syntax exists in C++ ?
This syntax exists because C had it, and C++ syntax was originally based on C.
There is no difference in the code behaviour of f(args) and (*f)(args).
I can't be sure if I am right, but here is a possible explanation:
Every function in c and as well as in c++ is a potential variable.
Possible declaration of function is:
int (*MyFunction)(int, double);
In this case- Variable name: MyFunction | Type: function that returns int with int, double parameters.
So, even when you declare function, you actually declare variable with a "function" type. In this case, it is make sense why can you use, in your case (*add)(3, 2) for function calling (or using a variable).
It may by more clearly for you to have a look on lambda expressions, which can make a function implementation, and then let you use it like a local function variable:
int(*MyFunction)(int, double) = [](int a, double b) -> int {
return (int)((a + b) * 10);
};
Here we declare on function type variable, and implement a function for it with a lambda expression. Now we can use it in two forms:
MyFunction(1, 2.5); // Like a regular function
(*MyFunction)(1, 2.5); // As a function type variable
Again, it is the most sense explanation that I could think of. I don't sure if it is a right/best/fully explanation, but I hope it gave you a new perspective of functions.
In my program, I would like to take the address of a temporary. Here is an example:
#include <iostream>
struct Number {
int value;
Number(int n) {
value = n;
}
};
void print(Number *number) {
std::cout << number->value << std::endl;
}
int main() {
Number example(123);
print(&example);
print(&Number(456)); // Is this safe and reliable?
}
This would output:
123
456
To compile, the -fpermissive flag is requied.
Here is my question: is this safe and reliable? In what possible case could something go wrong?
If your definition of "safe and reliable" includes "will compile and produce the same results if the compiler is updated" then your example is invalid.
Your example is ill-formed in all C++ standards.
This means, even if a compiler can be coerced to accept it now, there is no guarantee that a future update of your compiler will accept it or, if the compiler does accept the code, will produce the same desired effect.
Most compiler vendors have form for supporting non-standard features in compilers, and either removing or altering support of those features in later releases of the compiler.
Consider changing your function so it accepts a const Number & rather than a pointer. A const reference CAN be implicitly bound to a temporary without needing to bludgeon the compiler into submission (e.g. with command line options). A non-const reference cannot.
&Number(456) is an error because the built-in & operator cannot be applied to an rvalue. Since it is an error, it is neither safe nor reliable. "What could go wrong" is that the code could be rejected and/or behave unexpectedly by a compiler which follows the C++ Standard. You are relying on your compiler supporting some C++-like dialect in which this code is defined.
You can output the address of the temporary object in various ways. For example add a member function auto operator&() { return this; } . The overloaded operator& can be applied to prvalues of class type.
Another way would be to have a function that is like the opposite of move:
template<typename T>
T& make_lvalue(T&& n)
{
return n;
}
and then you can do print(&make_lvalue(Number(456)));
If you are feeling evil, you could make a global template overload of operator&.
This is fine but..
Number *a;
print(a); // this would be a null ptr error
How I would change it is
void print(const Number num) // make the paramater const so it doesnt change
{
std::cout << num.value << std::endl; // note the . instead of -> cuz this is a reference not a pointer
}
You would remove the "&" from your code like:
Number example(123);
print(example);
print(Number(456));
and if you need to pass a pointer you just put a "*" to dereference it.
chasester
In C++, there are two ways of passing a function into another function that seem equivalent.
#include <iostream>
int add1(int i){ return i+1; }
int add2(int i){ return i+2; }
template <int (*T)(int) >
void doTemplate(int i){
std::cout << "Do Template: " << T(i) << "\n";
}
void doParam(int i, int (*f)(int)){
std::cout << "Do Param: " << f(i) << "\n";
}
int main(){
doTemplate<add1>(0);
doTemplate<add2>(0);
doParam(0, add1);
doParam(0, add2);
}
doTemplate accepts a function as a template argument, whereas doParam accepts it as a function pointer, and they both seem to give the same result.
What are the trade-offs between using each method?
The template-based version allows the compiler to inline the call, because the address of the function is known at compile-time. Obviously, the disadvantage is that the address of the function has to be known at compile-time (since you are using it as a template argument), and sometimes this may not be possible.
That brings us to the second case, where the function pointer may be determined only at run-time, thus making it impossible for the compiler to perform the inlining, but giving you the flexibility of determining at run-time the function to be called:
bool runtimeBooleanExpr = /* ... */;
doParam(0, runtimeBooleanExpr ? add1 : add2);
Notice, however, that there is a third way:
template<typename F>
void doParam(int i, F f){
std::cout << "Do Param: " << f(i) << "\n";
}
Which gives you more flexibility and still has the advantage of knowing at compile-time what function is going to be called:
doParam(0, add1);
doParam(0, add2);
And it also allows passing any callable object instead of a function pointer:
doParam(0, my_functor());
int fortyTwo = 42;
doParam(0, [=] (int i) { return i + fortyTwo; /* or whatever... */ }
For completeness, there is also a fourth way, using std::function:
void doParam(int x, std::function<int(int)> f);
Which has the same level of generality (in that you can pass any callable object), but also allows you to determine the callable object at run-time - most likely with a performance penalty, since (once again) inlining becomes impossible for the compiler.
For a further discussion of the last two options, also see this Q&A on StackOverflow.
Template parameters
have to be known at compile time.
lead to one function instantation for every distinct value of the parameter (so-called template bloat)
the called function is transparant to the compiler (inlining, but could lead to even more bloat, double-edged sword)
the calling function can be overloaded for particular values of the parameter, without modifying existing code
Function pointers
are passed at run time.
only lead to one calling function (smaller object code)
the called function is typically opaque to the compiler (no inlining)
the calling function needs a runtime if/switch to do special stuff for special values of the parameter, this is brittle
When to use which version: if you need speed and a lot of customization, use templates. If you need flexibility at runtime, but not in the implementation, use function pointers.
As #AndyProwl points out: if you have a C++11 compiler, function pointers are generalized to callable objects such as std::function and lambda expressions. This opens up a whole new can of worms (in a good sense).
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
Are there benefits of passing by pointer over passing by reference in C++?
In both cases, I achieved the result.
So when is one preferred over the other? What are the reasons we use one over the other?
#include <iostream>
using namespace std;
void swap(int* x, int* y)
{
int z = *x;
*x=*y;
*y=z;
}
void swap(int& x, int& y)
{
int z = x;
x=y;
y=z;
}
int main()
{
int a = 45;
int b = 35;
cout<<"Before Swap\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(&a,&b);
cout<<"After Swap with pass by pointer\n";
cout<<"a="<<a<<" b="<<b<<"\n";
swap(a,b);
cout<<"After Swap with pass by reference\n";
cout<<"a="<<a<<" b="<<b<<"\n";
}
Output
Before Swap
a=45 b=35
After Swap with pass by pointer
a=35 b=45
After Swap with pass by reference
a=45 b=35
A reference is semantically the following:
T& <=> *(T * const)
const T& <=> *(T const * const)
T&& <=> [no C equivalent] (C++11)
As with other answers, the following from the C++ FAQ is the one-line answer: references when possible, pointers when needed.
An advantage over pointers is that you need explicit casting in order to pass NULL.
It's still possible, though.
Of the compilers I've tested, none emit a warning for the following:
int* p() {
return 0;
}
void x(int& y) {
y = 1;
}
int main() {
x(*p());
}
In fact, most compilers emit the same code for both functions calls, because references are generally implemented using pointers.
Following this logic, when an argument of (non-const) reference type is used in the function body, the generated code will just silently operate on the address of the argument and it will dereference it. In addition, when a call to such a function is encountered, the compiler will generate code that passes the address of the arguments instead of copying their value.
Basically, references and pointers are not very different from an implementation point of view, the main (and very important) difference is in the philosophy: a reference is the object itself, just with a different name.
References have a couple more advantages compared to pointers (e. g. they can't be NULL, so they are safer to use). Consequently, if you can use C++, then passing by reference is generally considered more elegant and it should be preferred. However, in C, there's no passing by reference, so if you want to write C code (or, horribile dictu, code that compiles with both a C and a C++ compiler, albeit that's not a good idea), you'll have to restrict yourself to using pointers.
Pass by pointer is the only way you could pass "by reference" in C, so you still see it used quite a bit.
The NULL pointer is a handy convention for saying a parameter is unused or not valid, so use a pointer in that case.
References can't be updated once they're set, so use a pointer if you ever need to reassign it.
Prefer a reference in every case where there isn't a good reason not to. Make it const if you can.
Here is a good article on the matter - "Use references when you can, and pointers when you have to."
Use references all the time and pointers only when you have to refer to NULL which reference cannot refer.
See this FAQ :
http://www.parashift.com/c++-faq-lite/references.html#faq-8.6
So I was just working with function pointers and I remembered that you could do this:
void Foo()
{
}
int main()
{
void(& func)() = Foo;
func(); //::Foo();
}
The obvious advantage being that references reference valid objects (unless they're misused), or functions in this case.
The obvious disadvantages being that you can't store an array of references and can't use them for member function pointers (at least as far as I can tell).
My question: does anyone use them (i.e., function references, not function pointers), and if so, in what scenarios have you found them useful/helpful?
The only place I can see them being useful off the bat is binding a reference to a certain function when working with conditional compilation.
I've used them before to add customization to classes by passing them to the constructor in a way like the strategy pattern
Function references, unlike function pointers, make it harder to create them from an invalid source. This is useful if you are making a wrapper around a C library - the C++ code can take a callback function by reference and pass the pointer to the C library if the lbrary requires that the passed pointer must not be NULL.
It is also a convenient way to alias a function, especially in C++11 with the new auto keyword:
#include <iostream>
#include <typeinfo>
void f(int i, char c)
{
std::cout << i << ' ' << c << std::endl;
}
int main()
{
std::cout << typeid(f).name() << std::endl; //FvicE
f(0, '1');
void (*pf)(int, char) (&f); //ugly
std::cout << typeid(pf).name() << std::endl; //PFvicE
(*pf)(2, '3');
pf(4, '5'); //works, but I don't recommend it
void (&rf)(int, char) (f); //still ugly
std::cout << typeid(rf).name() << std::endl; //FvicE
rf(6, '7');
auto &af (f); //pretty, but only works in C++11
std::cout << typeid(af).name() << std::endl; //FvicE, same as above
af(8, '9');
}
I think your example usage is quite good. Because if you would use an ordinary function pointer, and you then apply the address-of operator, you would get the address of the function pointer. Using a reference to function will do the expected thing, in that it returns a pointer to the function itself.
I also can't think of many examples. Keeping function references, as you point out, has some ugly consequences. Another possibly unwanted consequence is, if kept as a class-member, your objects will be non-assignable if you don't write your own operator= and refrain from trying to re-assign the function-reference.
I think most uses of function references are implicit, much like most uses of array-references - although much more so, when you accept arguments by-reference:
template<typename T>
void do_something(T const& t) { ... }
While accepting arrays by reference has the advantage of not losing their size information, accepting functions by reference explicitly doesn't seem to have an advantage (at least as far as I can see). I suppose the existence of function references largely is justified by the idealistic view of a reference as an alias-name of some object or function, together with the fact that it allows passing functions to such templates that accept their argument by reference.
I would probably avoid using them if I wouldn't need them inevitably. Constant function pointers also provide non-reassignable callables, and will probably avoid confusions when other programmers, who possibly are not very familiar with this language niches, read your code. Worth to note that Vandervoorde & Josuttis also recommend to avoid them to reduce confusion (in their book C++ Templates - The Complete Guide).
in addition to the use as strategy (as pointed out by Robert Gould), I freqently use them at the entrance point to (template) metaprogramming. A function reference can easily be picked up by a template parameter; from this point on it can be passed through several layers of (metaprogramming) templates. Of course, this holds true for a function pointer as well, but the reference is an alias and thus communicates the intention more clearly.
To give an example: when writing a generic command dispatching system for an application, a lot of different operations need to be announced as commands. We can use a simple "builder function" as front-end for the client code. Behind the scenes, this builder function picks up the actual function signature as template parameter, derives (by template metaprogramming) the actual parameter and return type values and possibly picks the suitable specialisation to store a "memento" and an "undo functor". These functors can than be stored either as function pointers internally, or using boost or tr1 or C++11 function objects. This way, it is possible to build a type safe command invocation and "undo" system.
I've used them in a plug-in system where plug-in DLLs could be loaded/unloaded at run-time. I would look for known symbols in each DLL and cast them to function pointers.