C ++ static_cast from float ** to void **

Just stumbled upon this:

#include <iostream> using namespace std; int main(int argc, char** argv) { float *a = new float[10]; void **b; b = static_cast<void**>(&a); delete(a); return 0; } macbook:C nils$ g++ -Wall -g -o static_cast static_cast.cpp static_cast.cpp: In function 'int main(int, char**)': static_cast.cpp:9: error: invalid static_cast from type 'float**' to type 'void**' macbook:C nils$ clang++ -Wall -g -o static_cast static_cast.cpp static_cast.cpp:9:9: error: static_cast from 'float **' to 'void **' is not allowed b = static_cast<void**>(&a); ^~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. macbook:C nils$ 

Why is this not allowed? While b = (void **) (& a); works.

+4
source share
4 answers

$ 5.2.9 / 2 -

"The expression e can be explicitly converted to type T using static_cast of the form static_cast (e) if the declaration is" T t (e) "; well-formed, for some I came up with a temporary variable t (8.5). The effect of such an explicit conversion is the same that both executing the declaration and initializing and then using the temporary variable as the result of the conversion.The result is an lvalue if T is a reference type (8.3.2) and the value is rvalue otherwise.The expression e is used as an l value if and only if initialization uses it as an lvalue. "

Let's look at code snippet 1 below

float *f;

void *p = f;

Here the initialization "p" is well formed. This corresponds to $ 4.2

An rvalue of type "pointer to cv T," where T is an object type, can be converted to an rvalue of type "pointer to cv void."

Now take the code in OP

In our case, "E" is 'float **' , and 'T' is 'void **'

So, will static_cast work for a conversion attempt if 'p' can be initialized as shown below.

float **f;

void **p = f;

The initialization of 'p' is poorly formed because it is not a valid condition specified in $4.10

Now, having come to why b = (void**)(&a); ?

In this case, an explicit cast is used ( $5.4 ). In this case, this explicit cast is equivalent to reinterpret_cast ( $5.4/5 ). In this particular case, this conversion is allowed ( $5.2.1/7 ).

Does it help?

+6
source

See Should I use static_cast or reinterpret_cast when casting void * for anyone .

you must use reinterpret_cast .

I used a static tide to distinguish it from a child class to a parent class or where I knew that type conversion was safe. If I need a runtime check, I would use dynamic_cast.

+2
source

When you write C-style, you basically bypass C ++ type checking so it is very "excusable". However, to comply with C ++ (and be safe), you must use C ++ casts static_cast, dynamic_cast, or reinterpret_cast.

reinterpret_cast is the closest you can get in C ++ for C-cast without actually doing C-cast.

+1
source

You probably don't want void** , but rather void* for the reason Joe Gauteren mentioned in this comment

+1
source

All Articles