18

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

}
Chad
  • 1,750
  • 2
  • 16
  • 32
myfaqbox3
  • 181
  • 1
  • 3

2 Answers2

20

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).

SirGuy
  • 10,660
  • 2
  • 36
  • 66
5

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;
IanPudney
  • 5,941
  • 1
  • 24
  • 39
  • More generally, in most contexts, an expression of function type (including a function name) is implicitly converted to a pointer to the function. Exceptions are when it's the argument to `sizeof` (which is illegal) or to unary `&` (which yields the address of the function). This applies even when the function name is followed by parentheses; a function call requires a pointer-to-function as its first operand. – Keith Thompson Jun 12 '13 at 19:10
  • 1
    BTW, casting a function pointer to `void*` is likely to work on most systems, but I don't believe the behavior is defined. (For example, the conversion could lose information if function pointers are bigger than `void*`.) – Keith Thompson Jun 12 '13 at 19:11
  • Is there a `(void*)pr` equivalent that is well-formed? Some sort of `(void_fnptr_t*)pr`? – Eljay Dec 13 '17 at 13:42