none
is it safe to cast interior_ptr<MyValueType> and interior_ptr<Object^> to interior_ptr<Int32> ? RRS feed

  • Question

  • 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.









    • Edited by renaudh Saturday, February 8, 2014 8:16 AM
    Saturday, February 8, 2014 8:05 AM

Answers

  • "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."

    It should be safe. As far as IL is concerned there's no such thing as interior_ptr<X>, there are only managed pointers (type & in IL speak). The type of the pointed object is irrelevant.

    • Marked as answer by renaudh Saturday, February 8, 2014 9:19 AM
    Saturday, February 8, 2014 8:57 AM
    Moderator

All replies

  • "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."

    It should be safe. As far as IL is concerned there's no such thing as interior_ptr<X>, there are only managed pointers (type & in IL speak). The type of the pointed object is irrelevant.

    • Marked as answer by renaudh Saturday, February 8, 2014 9:19 AM
    Saturday, February 8, 2014 8:57 AM
    Moderator
  • Thank you very much for your two answers !!!!

    These were the last 2 "hacks" I needed for my interpreter (the langage is pascal like, so with .NET it's now pascal.NET like) and I am very glad that someone like you (who is looking to be even more familiar with .NET internals than me) thinks that they are safe.

    Because of these byref parameters I add to re-code MethodInfo.Invoke (ILGenerator) allowing to pass byref params.

    Also the DyanamicMethod/ILGenerator/delegate Invoker is much faster than MethodInfo.Invoke, and so I still wonder why there is not in .NET framework another dynamic invoker like the one I coded.


    • Edited by renaudh Saturday, February 8, 2014 3:29 PM
    Saturday, February 8, 2014 9:17 AM