Why do two functions have the same address?
-
30-04-2021 - |
質問
Consider this function template:
template<typename T>
unsigned long f(void *) { return 0;}
Now, I print the addresses of f<A>
and f<B>
as:
std::cout << (void*)f<A> << std::endl;
std::cout << (void*)f<B> << std::endl;
Why do they print the same address if compiled in MSVS10? Are they not two different functions and therefore should print different addresses?
Updated:
I realized that on ideone, it prints the different address. MSVS10 optimizes the code, as the function doesn't depend on T
in any way, so it produces same function. @Mark's answer and comments on this are valuable. :-)
解決
Since the function doesn't depend on the template parameter, the compiler can condense all instantiations into a single function.
I don't know why you get 1
for the address.
Added by Nawaz:
I experimented with my real code, and concluded that what @Mark said above is very important here :
Since the function doesn't depend on the template parameter, the compiler can condense all instantiations into a single function.
I also came to a conclusion that if the function-body depends on T*
, not on T
, it still produces the same function for different type arguments in my real code (not on ideone, though). However, if it depends on T
, then it produces different functions, because sizeof(T)
differs (fortunately for me) for different type arguments.
So I added a dummy automatic variable of type T
in the function template, so that the function could depend on the size of T
so as to force it to produce different functions.
他のヒント
You need to cast to void *
:
std::cout << (void*)(ftype*)f<A> << std::endl;
std::cout << (void*)(ftype*)f<B> << std::endl;
If you cast to a function pointer (or several other classes of non-void pointers), it will be interpreted as a bool
by the operator<<
for std::ostream
(hence the 1
).
This is simply a case of undefined behavior because the results of casting a pointer to a function to a pointer to object type are undefined.
A more interesting expression to examine would bef<A> == f<B>
which should evaluate to true
if and only if A
and B
refer to the same type.