Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

g++ "calling" a function without parenthesis (not f() but f; ). Why does it always return 1?

Tags:

c++

g++

In c++ (GNU GCC g++), my code is "calling" a function without (). The function is not working, but compiles ok.

More surprisingly, the code always returns 1...

Is there any explanation?

I expected the function name to be just a regular pointer, but seems it's a bit different...

Did I get all 1's only by chance?

#include <iostream>
using namespace std;

void pr ()
{
    cout << "sth";
}

int main()
{

pr;
cout << pr;  // output: 1
cout << *pr; // output: 1
cout << &pr; // output: 1

}
like image 823
myfaqbox3 Avatar asked Jun 12 '13 18:06

myfaqbox3


2 Answers

You're not actually calling pr in your code, you're passing the function pointer to cout. pr is then being converted to a bool when being passed to cout. If you put cout << boolalpha beforehand you will output true instead of 1.

EDIT:
With C++11 you can write the following overload:

    template <class RType, class ... ArgTypes>
    std::ostream & operator<<(std::ostream & s, RType(*func)(ArgTypes...))
    {
        return s << "(func_ptr=" << (void*)func << ")(num_args=" 
                 << sizeof...(ArgTypes) << ")";
    }

which means the call cout << pr will print (func_ptr=<address of pr>)(num_args=0). The function itself can do whatever you want obviously, this is just to demonstrate that with C++11's variadic templates, you can match function pointers of arbitrary arity. This still won't work for overloaded functions and function templates without specifying which overload you want (usually via a cast).

like image 90
SirGuy Avatar answered Oct 05 '22 17:10

SirGuy


The name of a function, when used without parentheses, can be implicitly cast to a function pointer. In fact, when you dereference or reference it, it remains nothing but a function pointer, or a poointer to a function pointer, etc. These function pointers, when printed, are implicitly cast to bool, which is why they simply output 1. If you want to output the actual memory address of the function, cast it to a void pointer:

cout<<(void*)pr;
like image 24
IanPudney Avatar answered Oct 05 '22 15:10

IanPudney