6

I have defined some functions and I print their address like this:

#include<iostream>
#include <string>

using std::cout;

std::string func()
{
    return "hello world\n";

}

int func2(int n)
{
    if (n==0)
    {
        cout << func2 << std::endl;
        return 1;
    }

    cout << func2 << std::endl;

    return n + func2(n - 1);
}

//================================================
int main()
{
    int (*fun)(int) = func2;

    cout << fun;

    cout << std::endl << func2(3);
}

When I print the function's name (address) they all print 1 on my compiler (Mingw gcc 4.8 ).

Is it OK or it should differ?

2 Answers 2

3

It doesn't exist an overload of operator<< for std::ostream that takes a function pointer. Thus the operator<<(std::ostream&, bool) overload is prefered. The address of a function is always evaluated to true when converted to bool. Thus, 1 is printed.

Alternatevely, if a function pointer is not larger than the size of a data pointer, you could cast your function pointer to a void* via reinterpret_cast and evoke the operator<<(std::ostream&, void*) overload and thus get the actual address of the function printed.

int (*fun)(int) = func2;
std::cout << reinterpret_cast<void*>(fun) << std::endl;

Live Demo

However, as correctly Neil and M.M mentioned in the comments there's no standard conversion from a function pointer to a data pointer, and this could evoke undefined behaviour.

Alternatively, and in my humble opinion properly, you could format your function pointer as a char array buffer and convert its address to a string in the following way:

unsigned char *p = reinterpret_cast<unsigned char*>(&func2);
std::stringstream ss;
ss << std::hex << std::setfill('0');
for(int i(sizeof(func2) - 1); i >= 0; --i) ss << std::setw(2) 
                                              << static_cast<unsigned int>(p[i]);
std::cout << ss.str() << std::endl;

Live Demo

Sign up to request clarification or add additional context in comments.

4 Comments

Assuming that the size of a function pointer is not larger than the size of a data pointer. You should also add const to the cast to prevent accidents.
note: this conversion to void * is not required to exist
@M.M I know, mentioned the UB and proposed an alternative safer way.
@NeilKirk, mentioned the UB and proposed an alternative safer way.
0

You're not printing the address because it's now converted to a boolean value.

But you can do e.g. this:

std::cout << reinterpret_cast<unsigned long long int *>(func2) << std::endl;

Now you'll get the actual address.

5 Comments

Assuming that the size of a function pointer is not larger than the size of unsigned long long int. You should also add const to the cast to prevent accidents.
Yeah, well...in C++11 long long is at least 64 bits.
So? What if pointers are 128-bits in the future? Once they were only 16-bits.
This may cause an alignment violation, if it even exists .. there's no reason to use any pointer type other than void *.
Sorry my mistake.. I didn't spot the *

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.