Consider following simple program:
#include <iostream>
void foo() { }
int main() {
std::cout<<static_cast<void*>(foo);
}
It compiles fine on VC++
but g++
& clang++
gives compilation errors.
See live demo here ( VC++
)
See live demo here ( clang++
)
See live demo here ( g++
)
Diagnostics given by g++
& clang++
:
source_file.cpp: In function ‘int main()’:
source_file.cpp:4:38: error: invalid static_cast from type ‘void()’ to type ‘void*’
std::cout<<static_cast<void*>(foo);
^
So, the question is which compiler is right here according to C++ standard ? I think behaviour of g++
& clang++
is correct here. I know that I should use reinterpret_cast
here instead of static_cast
. Is this bug in VC++
compiler ? If answer depends on the specific standard of C++ then also I am curious to know about it.
GCC and Clang are correct, because the conversion you are attempting to perform is not among those that can be performed by static_cast
. Those conversions are enumerated in [expr.static.cast]. I will briefly summarize them with references to paragraphs in that section:
- Base to derived reference conversion (p2)
- Conversion to xvalue of reference-compatible type (p3)
- Conversion using the operand for direct-initialization (p4)
- Conversion to void (p6)
- Inverse of standard conversion sequence (p7)
- Integer/enum conversions (p9, p10)
- Base to derived pointer conversion (p11)
- Derived to base pointer-to-member conversion (p12)
- Void pointer to object pointer conversion (p13)
Furthermore, p5 says:
No other conversion shall be performed explicitly using a static_cast
.
The conversion of a function or function pointer to void*
is not among the conversions listed.
In particular, direct-initialization does not apply since there is no standard conversion from function pointer to void*
. According to [conv.ptr]/2:
A prvalue of type “pointer to cv T
,” where T
is an object type, can be converted to a prvalue of type “pointer
to cv void
”. The result of converting a non-null pointer value of a pointer to object type to a “pointer to
cv void
” represents the address of the same byte in memory as the original pointer value. The null pointer
value is converted to the null pointer value of the destination type.
Note that this only covers object pointers, not function pointers.
From this pointers-to-void reference:
Pointer to object of any type can be implicitly converted to pointer to void
[Emphasis mine]
And from this function reference:
Functions are not objects
That seem to indicate that pointers to functions simply can not be converted to void*
.