0

I'm learning about the reference of C++, and I tried the following code from Thinking in C++:

However, I found that if I didn't cast the reference to 'long' type, the reference for f and g is the same, which I think doesn't make sense, and their value are both 1 instead of a number displayed in hexadecimal, could anybody explain that?

Thanks.

include <iostream>
using namespace std;
int dog, cat, bird, fish;

void f(int pet) {
    cout << "pet id number:" << pet << endl;
}
void g(int pet) {
    cout << "pet id number:" << pet << endl;
}
int main() {
    int i,j, k;

    cout << "f() normal: " << &f << endl;
    cout << "f() long: " << (long)&f << endl;
    cout << "g() normal: " << &g << endl;
    cout << "g() long: " << (long)&g << endl;  
    cout << "j normal: " << &j << endl;  
    cout << "j long: " << (long)&j << endl;
    cout << "k: " << (long)&k << endl;

    k=2;
    cout << "k: " << (long)&k << endl;  
} // 

Result

f() normal: 1
f() long: 4375104512
g() normal: 1
g() long: 4375104608
j normal: 0x7fff6486b9c0
j long: 140734879939008
k: 140734879939004
k: 140734879939004
Hanfei Sun
  • 45,281
  • 39
  • 129
  • 237
  • 2
    these are not references, but the addresses of the functions. – juanchopanza Apr 25 '12 at 17:58
  • 1
    possible duplicate of [How to print function pointers with cout?](http://stackoverflow.com/questions/2064692/how-to-print-function-pointers-with-cout) – Michael Burr Apr 25 '12 at 18:01
  • It's probably an implicit cast to `bool`, try setting the boolean alpha flag in the stream and see if they change to `true` instead of `1`. – K-ballo Apr 25 '12 at 18:01
  • 2
    There no `ostream::operator<<()` overload for a function pointer, but there is for `void*`. `&j` will match the `void*` overload (which is why that seems to work), but function pointers will not - the best match they get is is the one for `bool`. – Michael Burr Apr 25 '12 at 18:03
  • *their value are both 1 instead of a hexadecimal*... Hexadecimal is just another way to represent a number. Just like decimal (base 10), binary (base 2), and hexadecimal (base 16). – Marlon Apr 25 '12 at 18:05

2 Answers2

4

Because ostream has an overload of operator<< for void* and any data pointer can be cast to void*, the addresses of ints like j are printed. However, function pointer can't be converted to void*, so this particular overload is out of way.

That's when another operator<< overload comes to play, in this case, it would be an overload for bool. The function pointer can be converted to bool (with true == pointer is non-NULL). The pointer to f is non-NULL, so it yields true in this conversion, which is printed as 1.

jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • I see. It's about overload. Why can't function pointer be converted to `void*`? I learned python before and thought function is just another form of data.. It seems different in C.. – Hanfei Sun Apr 25 '12 at 20:59
1

This has nothing to do with references. That program doesn't use any references. You're using the address-of operator &. See https://stackoverflow.com/a/9637342/365496

f() normal: 1              the address of f is converted to bool 'true' and printed 
f() long: 4375104512       the address of f is converted to an integer
g() normal: 1              the address of g is converted to bool 'true' and printed
g() long: 4375104608       the address of g is converted to an integer
j normal: 0x7fff6486b9c0   the address of j is printed directly (there's an operator<< for this but not one for printing function pointers like f and g)
j long: 140734879939008    the address of j is converted to an integer
k: 140734879939004         the address of k is converted to an integer
k: 140734879939004         the address of k is converted to an integer
Community
  • 1
  • 1
bames53
  • 86,085
  • 15
  • 179
  • 244