Just ran into 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 it not allowed? While b = (void**)(&a); works.
$5.2.9/2 -
"An expression e can be explicitly converted to a type T using a static_cast of the form static_cast(e) if the declaration “T t(e);” is well-formed, for some invented temporary variable t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization 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 an rvalue otherwise. The expression e is used as an lvalue if and only if the initialization uses it as an lvalue."
Let us take the case of Code snippet 1 as below
float *f;
void *p = f;
Here initialization of 'p' is well-formed. This is in accordance with $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 let us take the code in OP
In our case, 'E' is 'float **'
and 'T' is 'void **'
So, whether static_cast will work for the attempted conversion if 'p' can be initialized as shown below
float **f;
void **p = f;
The initialization of 'p' is ill-formed as it is not a valid condition listed under $4.10
Now, coming to why b = (void**)(&a);
works?
This is the case where an explicit cast is used ($5.4
). In this case, this explicit cast is equivalent of reinterpret_cast
($5.4/5
). In this particular case, this conversion is allowed ($5.2.1/7
).
Does this help?
See Should I use static_cast or reinterpret_cast when casting a void* to whatever.
you should use reinterpret_cast.
I've used static cast to cast from a child class to the parent class, or where I knew the the type conversion was safe. If I needed runt time verification, then I'd use dynamic_cast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With