Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++, can a C-style cast invoke a conversion function and then cast away constness?

GCC and Clang both reject the C-style cast in the following code.

http://coliru.stacked-crooked.com/a/c6fb8797d9d96a27

struct S {     typedef const int* P;     operator P() { return nullptr; } }; int main() {     int* p1 = const_cast<int*>(static_cast<const int*>(S{}));     int* p2 = (int*)(S{}); } 
 main.cpp: In function 'int main()': main.cpp:7:25: error: invalid cast from type 'S' to type 'int*'      int* p2 = (int*)(S{}); main.cpp:7:15: error: cannot cast from type 'S' to pointer type 'int *'     int* p2 = (int*)(S{});               ^~~~~~~~~~~ 

However, according to the standard, a C-style cast can perform the conversions performed by a static_cast followed by a const_cast. Is this code well-formed? If not, why not?

like image 285
Brian Bi Avatar asked Aug 29 '16 21:08

Brian Bi


People also ask

How to cast away constness c++?

The statement int* c = const_cast<int>(b) returns a pointer c that refers to a without the const qualification of a . This process of using const_cast to remove the const qualification of an object is called casting away constness. Consequently the compiler does allow the function call f(c) .

When should I use Static_cast?

This is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coersion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc.

What does const_ cast do?

const_cast is one of the type casting operators. It is used to change the constant value of any object or we can say it is used to remove the constant nature of any object. const_cast can be used in programs that have any object with some constant value which need to be changed occasionally at some point.

What is the commonly used casting function for casting the pointer to different objects of the classes in an inheritance hierarchy?

Use dynamic_cast for converting pointers/references within an inheritance hierarchy.


1 Answers

This is core issue 909:

According to 5.4 [expr.cast] paragraph 4, one possible interpretation of an old-style cast is as a static_cast followed by a const_cast. One would therefore expect that the expressions marked #1 and #2 in the following example would have the same validity and meaning:

struct S {   operator const int* (); };  void f(S& s)  {   const_cast<int*>(static_cast<const int*>(s));  // #1   (int*) s;  // #2 } 

However, a number of implementations issue an error on #2.

Is the intent that (T*)x should be interpreted as something like

const_cast<T*>(static_cast<const volatile T*>(x)) 

Rationale (July, 2009):

According to the straightforward interpretation of the wording, the example should work. This appears to be just a compiler bug.

This was apparently never resolved by neither Clang nor GCC. Time to open tickets.

like image 108
Columbo Avatar answered Sep 19 '22 21:09

Columbo