Dereferencing a function pointer

Nov 23, 2014 at 6:39am
I'm exploring function pointers as I think it will be a good way to do some curve parameterization stuff.
Given the following code,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
double func(int a, char c)
{
    return 3.14 + a + static_cast<int>(c);
}
#include <iostream>
int main()
{
    using namespace std;
    double (*pfunc) (int, char) = func;
    cout << *pfunc << endl;
    cout << pfunc(2, '\0') << endl;

    return 0;
}

Line 9 prints 1 to the console.

My question is just, what is happening here, and why does it happen to be 1?
Undefined behavior? It's also 1 on cpp.sh.
Last edited on Nov 23, 2014 at 6:47am
Nov 23, 2014 at 10:08am
You probably meant line 10.
Try this. It might shed some light on what happens here.
1
2
3
4
5
6
7
8
9
10
11
12
13
double func(int a, char c)
{
    return 3.14 + a + static_cast<int>(c);
}
#include <iostream>
int main()
{
    using namespace std;
    double (*pfunc) (int, char) = func;
    cout.setf(ios::boolalpha);
    cout << *pfunc << endl;
    cout << pfunc(2, '\0') << endl;
}
Nov 24, 2014 at 4:24am
Thanks (yeah line 10 woops), so dereferencing it like that returns a bool to represent it? Is there any useful point of this, and in what situation could it be false?
Nov 24, 2014 at 8:06am
so dereferencing it like that returns a bool to represent it?
No, it returns function which gets converted to the function pointer right away. Because there is no overload for << operator which takes function pointer it gets converted to nearest acceptable result: bool. Every pointer can be converted to bool, not only function pointers.

Is there any useful point of this, and in what situation could it be false?
Yes, there is. You can use it at the same situation you would use it with normal pointers — to check if pointer holds value:
1
2
3
4
5
6
7
void log(std:string s, std::ostream* out = nullptr)
{
    if(out) //If out parameter is not null
        *out << s;
    else
        std::clog << s;
}
void callback(int i, void(*)(int) foo = nullptr)
{
    if(foo) //If we are provided with function
        foo(i);
    else
        default_handler(i);
}
Nov 24, 2014 at 2:13pm
Thanks, the reason why *pfunc looks like bool makes sense now.

Edit : Although actually, one more question:
1
2
3
    double (*pfunc) (int, char) = nullptr; // setting it to null instead of a function
    cout.setf(ios::boolalpha);
    cout << *pfunc << endl;

This is defined behavior to display false, then?
It just seems really weird to be dereferencing something that looks like it's NULL, but I guess it's okay to do it if it's a function pointer and not just a regular pointer.
Last edited on Nov 24, 2014 at 2:24pm
Nov 24, 2014 at 2:33pm
I guess it's okay to do it if it's a function pointer and not just a regular pointer.
No, it is not. You should not dereference null pointers. Actually you should not dereference function pointers at all: in most cases they would just revert back to pointers immideately and in the only case where they are not (calling function immediately), you can just call it though pointer immediately:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
double func(int a, char c)
{
    return 3.14 + a + static_cast<int>(c);
}
#include <iostream>
int main()
{
    using namespace std;
    double (*pfunc) (int, char) = func;
    cout.setf(ios::boolalpha);
    cout << pfunc << endl; // No dereferencing: still bool context
    cout << pfunc(2, '\0') << endl; //No dereferencing, still calling correctly

    cout << (*pfunc)(2, '\0') << endl; //Calling though dereferenced pointer
    pfunc = nullptr;
    cout << pfunc; //No dereferencing
}

Nov 24, 2014 at 2:38pm
Okay. So basically even though the language gives you the ability to do it, there is no reason to dereference a function pointer without using it at the same time.
Once again thanks for your time.
Topic archived. No new replies allowed.