A-Sharabiani
A-Sharabiani

Reputation: 19329

How to convert a pointer of type void(*)() to void*

How to convert a pointer of type void(*)() to void *?

is any of the following operators can be used to do so?

Example: all of the following are compiled (tried in Visual Studio 2017), I wonder if they all have the same result after converting.

void operation(void(*callback)()) {

    void* test1 = callback;
    void* test2 = static_cast<void*>(callback);
    void* test3 = reinterpret_cast<void*>(callback);
}

Upvotes: 2

Views: 6595

Answers (2)

M.M
M.M

Reputation: 141554

In Standard C++, since C++11, it is conditionally-supported, which means that an implementation may or may not support it, and must document whether it is supported.

For implementations that do support this cast, the appropriate cast operator to use is reinterpret_cast. The details can be found in the C++14 standard [expr.reinterpret.cast]/8.

It's an error to try and convert a function pointer to an object pointer with no cast ([conv.ptr]), or with static_cast ([expr.static.cast]/5). If your compiler permits this in standard mode and doesn't issue a diagnostic then the compiler is non-conforming.

Upvotes: 3

Ben Voigt
Ben Voigt

Reputation: 283634

In ISO standard C++, there is no implicit conversion from any function pointer type to any object pointer type. So this line is ill-formed.

void* test1 = callback;

For the compiler to accept this without a diagnostic is a bug1 (you do have warnings enabled, correct?)

static_cast between any object pointer type and a function pointer type (either direction) is prohibited in standard C++. The controlling rule is found in 5.2.9:

Otherwise, the static_cast shall perform one of the conversions listed below. No other conversion shall be performed explicitly using a static_cast.

Since none of the rules above or below discuss function pointer casts, this forbids the line

void* test2 = static_cast<void*>(callback);

However, this is not necessarily a separate compiler bug, because one of the rules does permit static_cast to be used to accomplish any implicit conversion.

The final line is the only correct one:

void* test3 = reinterpret_cast<void*>(callback);

The controlling rule is provided in the specification for reinterpret_cast (5.2.10)

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.


1 When standard-compliant mode is enabled using /Za, the Microsoft C++ compilers do correctly reject the copy-initialization and static_cast attempts:

source_file.cpp(8): error C2440: 'initializing': cannot convert from void (*)(void) to void *

source_file.cpp(8): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

source_file.cpp(9): error C2440: static_cast: cannot convert from void (*)(void) to void *

source_file.cpp(9): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Upvotes: 4

Related Questions