Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do compilers behave differently when static_cast(ing) a function to void*?

The following code compiles without any error in VSC++2017 and doesn't compile in gcc 7.3.0 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’ void* p = static_cast<void*>(func))

#include <iostream>

int func(int x) { return 2 * x; }

int main() {

    void* p = static_cast<void*>(func);
    return 0;
}
like image 826
Soulimane Mammar Avatar asked Mar 24 '19 00:03

Soulimane Mammar


People also ask

What does static_cast void do?

If, in your code, you know you do not need a result somewhere, you can use the static_cast<void> method to mark the result as discarded – but the compiler will consider the variable used then and no longer create a warning or error. When compiled with g++ -std=c++14 -Wall example.

What is the point of static_cast?

The static_cast operator converts variable j to type float . This allows the compiler to generate a division with an answer of type float . All static_cast operators resolve at compile time and do not remove any const or volatile modifiers.

What is the purpose of reinterpret_cast and how does it differ from a regular cast?

reinterpret_cast is a type of casting operator used in C++. It is used to convert a pointer of some data type into a pointer of another data type, even if the data types before and after conversion are different. It does not check if the pointer type and data pointed by the pointer is same or not.

Why do we need reinterpret_cast?

The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function.


1 Answers

Functions are implicitly convertible only to function pointers. A function pointer is not a pointer in the strict meaning of the word in the language, which refers only to pointers to objects.

Function pointers cannot be converted to void* using static_cast. The shown program is ill-formed. If a compiler does not warn, then it fails to conform to the standard. Failing to compile an ill-formed program does not violate the standard.


On systems where void* is guaranteed to be able to point to a function (such as POSIX), you can use reinterpret_cast instead:

void* p = reinterpret_cast<void*>(func);

But this is not portable to systems that lack the guarantee. (I know of no system that has a C++ compiler and does not have this guarantee, but that does not mean such system does not exist).

Standard quote:

[expr.reinterpret.cast]

Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning of such a conversion is implementation-defined, except that if an implementation supports conversions in both directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification, shall yield the original pointer value.

Note that this conditional support does not extend to pointers to member functions. Pointers to member functions are not function pointers.

like image 74
eerorika Avatar answered Oct 02 '22 20:10

eerorika