19

How can I compare function pointers in C++? Is it stable?

For example, would something like this be valid:

if(pFnc == &myFnc){
//Do something
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
user965369
  • 5,413
  • 13
  • 33
  • 47
  • What do you mean by *stable*? The order of generation of two functions in different runs of the compiler? The location of the functions within one particular run of the application? What about dynamic libraries, do you care about them? – David Rodríguez - dribeas Oct 15 '12 at 14:56
  • That's what I mean surely there's problems when It comes to more complex systems like that?! – user965369 Oct 15 '12 at 14:58
  • 1
    What is the question? In what scope you want to consider stability and what is the meaning of stability you want to pursue? Without that this is not a proper question and I will be the first one to vote to close. – David Rodríguez - dribeas Oct 15 '12 at 15:03
  • Well as you pointed out, the stability of this comparison depends on the scope of stability you're considering. I am building an application in MFC and I am comparing the address of certain WndProc functions. So in this scope, would it be stable? – user965369 Oct 15 '12 at 15:07
  • 2
    If you are looking for exact comparison (i.e. `==`) it is correct. For any inequality the order is undefined but stable within a single run of the application (assuming it is not a loaded dll), probably across multiple executions of the same binary (again, no dlls involved). If dlls are involved, the order will be maintained as long as the dll is not reloaded... for anything else all your bets are off (this also applies to `==`: if you unload and reload the dll it might not test for equality, as it might have been loaded at a different address... – David Rodríguez - dribeas Oct 15 '12 at 15:10
  • By "stable", you appear to be worried that the addresses of functions in a DLL might change, that the system will move those functions around. That's not the case. The only thing that can change this is to unload the library. In that case, you had better not have any dangling pointers to functions in that library. It's no different than pointers to data that have been deleted. – David Hammen Oct 15 '12 at 16:03
  • One should also understand: Does the expression `&myFnc` always have the same value, no matter what file, context, compiler optimizations, linkage, inlining, etc. where used? Do `&myFnc1` and `&myFnc2` always have _different_ values? I don't have the answers... :-( – Pablo H Jan 01 '21 at 23:50

3 Answers3

19

C++03 5.10/1 [expr.eq]:

The == (equal to) and the != (not equal to) operators have the same semantic restrictions, conversions, and result type as the relational operators except for their lower precedence and truth-value result. [Note: a < b == c < d is true whenever a < b and c < d have the same truth-value. ] Pointers to objects or functions of the same type (after pointer conversions) can be compared for equality. Two pointers of the same type compare equal if and only if they are both null, both point to the same function, or both represent the same address (3.9.2).

Emphasis mine.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
John Dibling
  • 99,718
  • 31
  • 186
  • 324
2

The function pointer is essentially a memory address like any other pointer in C++. So when comparing pointers you are always comparing memory addresses not values which means that it doesn't matter what those pointers point to as long as both pointers are of the same type.

Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100
0

Both pFnc and myFnc have to be defined. The correct comparison would be:

if(pFnc == myFnc)
{
    //Do something
}
Donotalo
  • 12,748
  • 25
  • 83
  • 121
  • myFnc is just a function at global scope, surely in your code you're just comparing a pointer value to an actual value? Wrong?! – user965369 Oct 15 '12 at 14:56
  • 4
    A function name acts as a pointer. You don't need to use `&myFnc`. – Donotalo Oct 15 '12 at 14:57
  • 2
    You can use both. The compiler will auto dereference a function if it is used as a pointer, but its always good to specifically deref yourself – SwiftMango Oct 15 '12 at 14:58
  • 2
    @Donotalo: Why you don't need the `&`, claiming that removing it makes it *more correct* is stretching it out. I claim that it is more correct with the `&`, as that is what will eventually be interpreted by the compiler... (I don't really want to advocate for one or the other and don't care to discuss it, but I don't quite like the claim of this option being *the correct* one) – David Rodríguez - dribeas Oct 15 '12 at 15:07
  • A function doesn't have "an actual value"; it is a function. That's why a function name acts as a pointer. – Lightness Races in Orbit Oct 15 '12 at 15:13
  • @DavidRodríguez-dribeas: opinions! :) – Donotalo Oct 15 '12 at 15:13
  • I agree that this is arguably "less correct". It's moving further from explicitness and letting the language fill in the blanks. There's nothing technically wrong with it, but without the `&` you (and your compiler, in some scenarios!) begin to wonder whether it is the `&` that's missing or a `()`. Why not write what you mean? – Lightness Races in Orbit Oct 15 '12 at 15:14
  • @LightnessRacesinOrbit: I see your point. The way I see it is that `myFunc` is a function. The name `myFunc` acts as a `pointer`. `&myFunc` would refer to `address of that pointer`, which is not the case here anyway. So I prefer `myFunc` directly. :) – Donotalo Oct 15 '12 at 15:20
  • 3
    @Donotalo: No, only when used as an *rvalue* the function decays to a pointer, but in `&myfunc` the identifier is an *lvalue* and it does not decay. `&myfunc` **is** the address of the function. Your last comment sounds like *I want to live in the falacy that a function **is** a pointer and act as if it were*, but a function is not a pointer in the same way that an array is not a pointer. This is actually more of a reason to type the `&`: avoid confusing the function with a pointer! – David Rodríguez - dribeas Oct 15 '12 at 15:27
  • What would if (*pFnc == myFnc) {} do? – TheMathemagician Oct 15 '12 at 15:35