Why are (member) function pointers behaving so weirdly in Visual C++?

后端 未结 3 1989
太阳男子
太阳男子 2020-12-14 06:48

I\'ve had a really bizarre problem that I\'ve reduced to the following test case:

#include 
#include 
#include 

str         


        
相关标签:
3条回答
  • 2020-12-14 07:21

    C++11 5.3.1 describes what & does; in this instance, it gives you a pointer to the member function in question, and the passage makes no requirement that this pointer must be unique.

    However, 5.10/1 says about ==:

    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.

    The question then becomes... are test1 and test2 "the same function"?

    Though the optimizer has collapsed them into a single definition, arguably the two names identify two functions and, as such, this would seem to be an implementation bug.

    (Note, though, that the VS team don't care and consider it "valid enough" to warrant the benefits of the optimisation. That, or they don't realise that it's invalid.)

    I'd stick to using the strings as "handles" for your function pointers.

    0 讨论(0)
  • 2020-12-14 07:26

    It turns out Visual C++'s linker can merge functions with identical definitions into one.
    Whether that's legal or not according to C++, I have no idea; it affects observable behavior, so it looks like a bug to me. Someone else with more information may want to chime in on that though.

    0 讨论(0)
  • 2020-12-14 07:42

    This is a by-product of what Visual C++ refers to as Identical COMDAT Folding (ICF). It merges identical functions into a single instance. You can disable it by adding the following switch to the linker commandline: /OPT:NOICF (from the Visual Studio UI it is found under Properties->Linker->Optimization->Enable COMDAT Folding)

    You can find details at the MSDN article here: /OPT (Optimizations)

    The switch is a linker-stage switch, which means you won't be able to enable it just for a specific module or a specific region of code (such as __pragma( optimize() ) which is available for compiler-stage optimization).

    In general, however, it is considered poor practice to rely on either function pointers or literal string pointers (const char*) for testing uniqueness. String folding is widely implemented by almost all C/C++ compilers. Function folding is only available on Visual C++ at this time, though increased widespread use of template<> meta-programming has increased requests for this feature to be added to gcc and clang toolchains.

    Edit: Starting with binutils 2.19, the included gold linker supposedly also supports ICF, though I have been unable to verify it on my local Ubuntu 12.10 install.

    0 讨论(0)
提交回复
热议问题