Func == &Func ?

D619d95cddb1edb227f51ef539d15cdc
0
Nautilus 103 Apr 23, 2012 at 23:19

I thought I knew every little nook of the C++ syntax - but this one strikes me as new.

#include <windows.h>

int Sum (int a, int B)
{
    return a + b;
}

void main void ()
{
    DWORD a = DWORD (DWORD_PTR (PDWORD ( Sum)));
    DWORD b = DWORD (DWORD_PTR (PDWORD (&Sum)));
}

How is it that a is equal to b?
If the ampersand in front of a function name is completely ignored -as it seem-, shouldn’t the compiler raise at least a warning? Mine won’t, not even with the /W4 switch.

5 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Apr 23, 2012 at 23:31

Yeah, it’s an oddity, but “Sum” and “&Sum” are both valid ways to get the address of a function. It’s not really consistent with anything else, but as functions are not first-class values in C++, it doesn’t screw anything up to have it this way. :)

D619d95cddb1edb227f51ef539d15cdc
0
Nautilus 103 Apr 24, 2012 at 00:42

@Reedbeta

it doesn’t screw anything up to have it this way. :)

This oddity :) had me set on a wild goose chase for an hour. I was typecasting the product of an &Func back in the wrong way - eventually de-referenceing twice what wasn’t a ‘pp’. My syntax looked correct. I was lucky to mis-edit-and-continue and notice that it’d make no difference.

Regards,
Ciao ciao : )

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Apr 24, 2012 at 00:54

That’s unfortunate, but I’d argue that the casting is at least as much to blame as much as the function address syntax, since it hides compiler errors that would ordinarily catch mistakes like that. :) Granted that casts are sometimes unavoidable in C/C++, though.

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Apr 24, 2012 at 07:58

Actually, Func and &Func are not the same. The first is a reference, the second is a pointer. The point is that the function call operator works on both types (which makes calling pointers to functions convenient), and that the reference can decay into a pointer (which is why you can reinterpret_cast them both to an integral type).

What I find weird though is that static_casts to other pointer types are not allowed, let alone static_casts to integral types, so I’m confused why your code would even compile in the first place.

D619d95cddb1edb227f51ef539d15cdc
0
Nautilus 103 Apr 24, 2012 at 14:04

You’re right of course, and static_cast raises the C2440 error for me too.
However I find this arguable:

int (*fpSum_ref) (int, int) =  Sum;
int (*fpSum_ptr) (int, int) = &Sum;

int Res = (*fpSum_ref) (1, 2);
    Res =   fpSum_ref  (1, 2);

    Res = (*fpSum_ptr) (1, 2);
    Res =   fpSum_ptr  (1, 2);

I’ll welcome the syntactic sugar, but this much freedom washes out the difference between Func and &Func. Looks weak to me, and paves the way for embarassing bugs (like the one I had yesterday - not even a catch(…) would shield me from the crash).