Reputation: 1978
Does the C++ standard define a particular behaviour if you make an old C-style cast from type A to type B where type A cannot be cast to type B and vice versa?
Would there be a known visible behavior that can be assumed to be symptom of a illegal cast in runtime using this?
Upvotes: 2
Views: 700
Reputation: 1916
Compiler will catch some of them, but not all. Here is an example of a disastrous cast:
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(std::string s, int x) : m_s(s), m_x(x) {}
void print() { cout << "A::print(): str = " << m_s << ", x = " << m_x << endl; }
private:
std::string m_s;
int m_x;
};
class B {
public:
B(int x) : m_x(x) {}
void print() { m_x++; cout << "B::print(): x = " << m_x << endl; }
private:
int m_x;
};
int main(int argc, char **argv) {
A *a = new A("abc", 1);
a->print();
B *b = (B*)a;
b->print();
a->print();
return 0;
}
Result on gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609:
A::print(): str = abc, x = 1
B::print(): x = 24828977
A::print(): str = bc, x = 1
Yes, we called B's methods on A's data, which means that our C-style cast worked as reinterpret_cast
. reinterpret_cast
just takes a memory region and allows you to treat is as something different. No seatbelts here.
On the other hand, if you try to compile something like this
A a;
B b;
a = (A)b;
return 0;
it will result in static_cast
and compile-time error. So C-style casting result depends on context.
This is NIGHTMARE when dealing with templates and auto
.
To avoid this problem, use static_cast
(for compile-time checks) and dynamic_cast
(for runtime checks) or reinterpret_cast
(for pointers and POD), clearly stating your intent.
Upvotes: 0
Reputation: 42838
Only one of the four C++-style casts determines the validity of the cast at runtime, namely dynamic_cast
.
A C-style cast corresponds to a combination of the other three casts (static_cast
, reinterpret_cast
, const_cast
). The validity of those casts is determined at compile-time, or if it cannot be determined at compile-time then the cast is assumed to be valid. A C-style cast never acts like dynamic_cast
.
So a C-style cast that "fails" at runtime, i.e. breaks the validity assumption, causes undefined behavior. So:
Does the C++ standard define a particular behaviour if you make an old C-style cast from type A to type B where type A cannot be cast to type B and vice versa?
No.
Would there be a known visible behavior that can be assumed to be symptom of a illegal cast in runtime using this?
No.
Upvotes: 4