0

I was playing around with function pointers recently, when I discovered that the value of the function pointer as printed by std::cout always evaluates to 1.

However that was not the case with printf(), and it prints the expected result.

It'd be great if someone could explain the reason behind such behavior.

Below is the code sample for reference.

#include<iostream>

using namespace std;

int  fun(int a)
{
    return 0;
}

int main()
{

    cout<<(&fun)<<endl; //always prints 1
    printf("%u",&fun); //this prints the expected result

    return 0;
}
kocica
  • 6,412
  • 2
  • 14
  • 35
Ashutosh
  • 529
  • 5
  • 15
  • 1
    g++: _warning: the address of 'int fun(int)' will always evaluate as 'true'_ – CIsForCookies Aug 14 '17 at 11:25
  • 1
    It looks like `cout` don't know type of pointer to your function, and transform it to `boolean` – Arkady Aug 14 '17 at 11:25
  • Also, `"%u"` is not the correct `printf()` format specifier for an address and is thus undefined behavior. The correct format specifier for a `void *` is `%p`, so you have to cast to `void *`. – Andrew Henle Aug 14 '17 at 11:26
  • If you are using printf, you might want to include the proper header – CIsForCookies Aug 14 '17 at 11:30
  • Which compiler `cout` prints `1`? Try the very code on other Compilers and you'll get a different results. I guess it's a UB. – Raindrop7 Aug 14 '17 at 11:43

2 Answers2

4

The printf call is simply undefined behavior. A function pointer is not an unsigned integer, and thus supplying it for a %u argument is not valid. (Try running this code on a 64-bit platform. You won't get the correct function pointer value.)

The cout on the other hand is type-safe. The compiler sees a function pointer argument and tries to find the best printing function (operator<< overload) it can. There is no such overload for function pointers themselves and the pointers don't offer a lot of implicit conversions. There is just one overload that works, and that is the one for bool. So the compiler converts the non-NULL function pointer to true and passes that. The overload then prints this as 1, but you could use the std::boolalpha modifier to make it print as true instead.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
1

Your cout treats (&fun) as a boolean expression and warns that it will always evaluate to true (i.e. non-zero).

Try casting it to void* as addresses should be printed, and check what happens:

#include <iostream>
#include <stdio.h>
using namespace std;

int  fun(int a){
    return 0;
}

int main(){

    cout<<(void*)(&fun)<<endl; //always prints 1

    /* Side note: This will print the same as above */
    // cout<<(void*)(fun)<<endl;  // note the missing &

    printf("%p",(void*)&fun); //this prints the expected result
    // while(1);
    return 0;
}

output on mu machine:

0x401460
0x401460
CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
  • Why have you got `while(1);`? – Ed Heal Aug 14 '17 at 11:30
  • I use it to ensure the cmd window is not closed when I open it for execution – CIsForCookies Aug 14 '17 at 11:32
  • 1
    It should be responsibility of your enviroment, not your program. Strictly speaking, infinite loops like this are UB. – Revolver_Ocelot Aug 14 '17 at 11:33
  • @Revolver_Ocelot didn't know that, thx! BTW, I use a batch script that compiles my code and executes it, thus I use the _while(1);_ as a fix. what would be a better way? – CIsForCookies Aug 14 '17 at 11:35
  • 1
    `pause` command in the batch file, for example. – Revolver_Ocelot Aug 14 '17 at 11:58
  • 1
    How is an In finite loop ub? – Ed Heal Aug 14 '17 at 12:57
  • _Note that it means that a program with endless recursion or endless loop (whether implemented as a for-statement or by looping goto or otherwise) has undefined behavior._ from https://stackoverflow.com/questions/41320725/is-infinite-loop-still-undefined-behavior-in-c-if-it-calls-shared-library – CIsForCookies Aug 14 '17 at 13:01
  • @Revolver_Ocelot I don't think they're UB, but they definitely can be optimized out. – Petr Skocik Aug 14 '17 at 13:11
  • Perhaps read https://stackoverflow.com/questions/1775865/preventing-console-window-from-closing-on-visual-studio-c-c-console-applicatio – Ed Heal Aug 14 '17 at 13:30
  • some of the solutions there suggest `getchar()` which is not very far from `while(1)` IMO. I eventually changed my batch call to `start /wait "C:...` – CIsForCookies Aug 14 '17 at 13:33