Is that code safe ? (GetInterior_ptr)
using namespace System;
ref struct A {
String ^s;
Object ^o;
};
interior_ptr<Int32> GetInterior_ptr(A ^a) {
interior_ptr<String^> ip = &a->s;
return (interior_ptr<Int32>)ip;
}
void *getAdr(interior_ptr<Int32> ip) {
pin_ptr<Int32> pi = ip;
return pi;
}
void *getAdr(A ^a) {
return *(void**)&a;
}
void callGC() {
GC::Collect();
GC::WaitForPendingFinalizers();
}
void TestInterior_ptr() {
A ^a = gcnew A(); a->s = "hello"; a->o = gcnew cli::array<Int32>(20000);
interior_ptr<Int32> ip = GetInterior_ptr(a);
void *old_ip_adr = getAdr(ip);
void *old_a_adr = getAdr(a);
callGC();
void *new_ip_adr = getAdr(ip);
void *new_a_adr = getAdr(a);
bool ip_adr_Changed = new_ip_adr != old_ip_adr;
bool a_adr_Changed = new_a_adr != old_a_adr;
interior_ptr<String^> ip2 = (interior_ptr<String^>)ip;
*ip2 += "world";
if (ip_adr_Changed && a_adr_Changed) {
Console::WriteLine("cool address changed and nothing crashed");
}
else if (ip_adr_Changed || a_adr_Changed) {
throw gcnew Exception("very bad : should crash");
}
}int main(array<System::String ^> ^args) { while(1) TestInterior_ptr(); return 0; }
the breakpoint I set on
if (...) { Console::WriteLine("cool address changed and nothing crashed"); }
is trigerred and nothing crashes so I guess that means it's safe to cast interior_ptr<X> to interior_ptr<Y> as far as you don't access to it with the wrong type.
Thank you for your opinion.