Possible Duplicate:
Regular cast vs. static_cast vs. dynamic_cast
Undefined, unspecified and implementation-defined behavior
I am facing a strange issue. In the following snippet I define a class
class NewClass
{
public:
void Test()
{
cout<<"NewClass Test"<<endl;
}
};
In my main() method, I write:
void main()
{
int *ptr = new int();
NewClass *n = ((NewClass *)ptr);
n->Test();
}
and it displays “NewClass Test”. I dont understand how its possible to type-cast any pointer to NewClass and still have it working.
Thanks in advance!
That’s static dispatch at work.
thisis really unnecessary in this case (e.g. it is not used or relied upon withinNewClass::Test()).Casting as
NewClass *n = ((NewClass *)ptr);is type conversion by address, and there is no type checking in this context. In other words, you’re not creating a newNewClassinstance anywhere, you are simply treating the memory at the address specified by theint*as aNewClass*. This is a dangerous conversion which should be avoided. In the event you need to funnel an object through an address where there type safety is lost (e.g.void*), always be sure both ends know what is sent and received. Fortunately, erasing type safety is becoming less common.The results are undefined, but you should expect bad side effects in most cases and you should avoid reinterpreting data as such at all costs.
In this case, the compiler likely inserted the results because it knew them. Furthermore, no error was exhibited because there is no actual dependence on the address or state of the object in this case:
Test()does not rely on the state/data/members/dynamic methods/vtable ofthis.If you were to add members such as
std::strings toNewClassand print those as well… you can expect things to blow up sooner than they do now 🙂In the event the dangers are not evident: This is an extrememly dangerous conversion — all the data backed by the
int*is being reinterpreted asNewClass*, and all of its internal memory and structure (e.g. vtables and magic cookies) are reinterpreted accordingly. It won’t take long before your program seg faults, either by reading beyond the end of the allocation (int*), or by treating anintas a completely unrelated type — in this case, consider the memory layout of a class with a vtable or data, such as adding somestd::strings to theNewClass, and reading from and writing to those members.