Check if X is derived from Y via typeid

I need to convert pointers to long (SendMessage ()) and I want to safely check if the variable on the other side is correct. So I thought about doing dynamic_cast, but that doesn't work on classes that are not virtual. Then I thought about doing the typeid, but that will work until I pass the derived var as the base.

Is there a way to check if a pointer is what I expect at runtime? Is there a way I can use typeid to see if a pointer is a type derived from a specific base?

0


source to share


7 replies


If all you have is this long

, then you really cannot do it. There is no general way to determine if an arbitrary number is a valid memory address. And even if you know that this is the correct memory address, there is no way to determine the type of object that the pointer points to. If you cannot be sure of the actual type of item before its address was added to long

, you cannot be sure what will be safe to use long

for whatever type you plan to use when casting it to.



You just need to trust that the sender of the message sent you a valid value. The best thing you can do is take some precautions to reduce the impact on your own program when it gets a fictitious value.

+1


source


Your link to SendMessage()

makes sounds like MS Windows is your platform, then the Pointer Rules (Windows) reading is recommended . It describes the features PtrToLong

and PtrToUlong

other things that Microsoft provides you in such situations.



+3


source


You cannot use typeid. This will result in an Access Violation if you get garbage instead of a valid pointer, so your check is meaningless.

What you should do is wrap your SendMessage and the code that handles the message in a single, type-safe interface. This way, you won't be able to send unexpected SendMessage things, and you won't need any checks on the receiver side.

A C ++ type system works at compile time. When you hit a long pointer, you will lose all type information. Long number of bits in memory; you cannot determine that it points to an object.

+1


source


PTLib ( http://sourceforge.net/projects/opalvoip/ ) uses the PCLASSINFO macro to define relationships between classes. This provides functions such as IsDescendant and GetClass.

Perhaps you could implement something similar.

0


source


dynamic_cast works by checking the signature of the virtual method table. If you don't have virtual methods, you don't have a VMT, as you say dynamic_cast won't work. However, if you don't have a VMT, you have absolutely no knowledge of the object being pointed to.

Your best bet is to require pointers to be in classes with at least one virtual method, even if it's a dummy. Then dynamic selection will be performed.

0


source


I still don't understand what your question is about.

  • If so, you can be sure that casting for long and backwards will give the same value, review the safe type checking of the variable
    Considering that there is a different responder linked on the MS-Site Pointer Usage Rules, the correct type to pass is UINT_PTR

    . So you do UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr);

    to cast to an integer type, and do the opposite to put it back into a pointer again. The C ++ standard guarantees that the original value is restored. (see the link above for my explanation of this). This Microsoft site, by the way, also says that WPARAM and LPARAM change their size depending on the platform. So you can just use this variable v

    and SendMessage

    it.
  • If you can check on the other hand if a pointer (converted to some pointer type) points to some object, the answer is you can't . Since you do not seem to know what type of pointer was used to send it, you cannot check on the receiving end what the dynamic type the pointer points to. If you know the type of the sender-side pointer, your check won't be needed in the first place.
0


source


On Windows, MFC provides a method to check if a given pointer is pointing to a valid memory location (this is done by catching a segfault). I don't remember the name of the function, but it is there. However, it does not guarantee that the contents of the specified memory will be valid. It may still have an invalid VMT and crash your code. You can of course capture the segfault yourself ( see MS Knowledge Base )

As far as checking that something is of a type, you must have a base class to start with. If you make the base class destructor "virtual", all derived classes will have a VMT.

If you are to avoid VMT at all costs, you must have some kind of discriminator that tells you what you are dealing with, such as the type of event in MS Windows events.

0


source







All Articles