Any reason to prefer static_cast over a chain of implicit conversions? - c++

Suppose I have a class implementing several interfaces
class CMyClass : public IInterface1, public IInterface2 { };
and in a member function of that class I need to obtain a void* pointer to one of those interfaces (typical situation in IUnknown::QueryInterface().
The typical solution is to use a static_cast to achieve pointer adjustment:
void* pointer = static_cast<IInterface2*>( this );
and it is safe in this case if there's no known class inherited from CMyClass. But if such class exists:
class CDerivedClass : public CUnrelatedClass, public CMyClass {};
and I accidentially do
void* pointer = static_cast<CDerivedClass*>( this );
and this is actually a pointer to CMyClass instance the compiler won't catch me and the program might run into undefined behavior later - static_cast becomes unsafe.
The suggested solution is to use implicit conversion:
IInterface2* interfacePointer = this;
void* pointer = interfacePointer;
Looks like this will solve both problems - pointer adjustment and risk of invalid downcast.
Are there any problems in the second solution? What could be the reasons to prefer the first one?

You could use this template:
template<class T, class U> T* up_cast(U* p) { return p; }
usage:
struct B {};
struct C : B {};
int main()
{
C c;
void* b = up_cast<B>(&c);
}
Note that the '*' is implicit. If you prefer up_cast<B*>, adjust the template accordingly.

Assigning to void* is always unsafe. Whichever way you write it you can mess up - assuming that the user is trying to QI for Interface1, then neither of the following will be a warning or error:
Interface2* interfacePointer = this;
void* pointer = interfacePointer;
or
void* pointer = static_cast<Interface2*>( this );
Given the tiny risk of accidentally using a static_cast to up cast, in a file that most likely wont even have access to the definition of the derived class, I see a lot of extra effort for very little actual safety.

I can't see any reason in not using the latter solution other than the fact that, if somebody else is reading your code it won't communicate immediatly why you are using such a convoluted statement ("why isn't he just using a static_cast?!?"), so it would be better to comment it or make the intent very clear.

Your analysis looks sound to me. The reason not to use your implicit approach are not compelling:
slightly more verbose
leaves variables hanging around
static_cast<> is arguably more common, therefore more likely to be obvious to other developers, searched for etc.
in many cases even the declarations of derived classes won't appear before the definition of the base class functions, so there's no potential for this type of error

If you are afraid of doing something by accident with the static_cast then I suggest that you wrap the casting/interface pointer obtaining into some template function, e.g. like this:
template <typename Interface, typename SourceClass>
void set_if_pointer (void * & p, SourceClass * c)
{
Interface * ifptr = c;
p = ifptr;
}
Alternatively, use dynamic_cast and check for the NULL pointer value.
template <typename Interface, typename SourceClass>
void set_if_pointer (void * & p, SourceClass * c)
{
p = dynamic_cast<Interface *>(c);
}

Related

Is there a way to simulate downcasting by reference

So, I have something along the lines of these structs:
struct Generic {}
struct Specific : Generic {}
At some point I have the the need to downcast, ie:
Specific s = (Specific) GetGenericData();
This is a problem because I get error messages stating that no user-defined cast was available.
I can change the code to be:
Specific s = (*(Specific *)&GetGenericData())
or using reinterpret_cast, it would be:
Specific s = *reinterpret_cast<Specific *>(&GetGenericData());
But, is there a way to make this cleaner? Perhaps using a macro or template?
I looked at this post C++ covariant templates, and I think it has some similarities, but not sure how to rewrite it for my case. I really don't want to define things as SmartPtr. I would rather keep things as the objects they are.
It looks like GetGenericData() from your usage returns a Generic by-value, in which case a cast to Specific will be unsafe due to object slicing.
To do what you want to do, you should make it return a pointer or reference:
Generic* GetGenericData();
Generic& GetGenericDataRef();
And then you can perform a cast:
// safe, returns nullptr if it's not actually a Specific*
auto safe = dynamic_cast<Specific*>(GetGenericData());
// for references, this will throw std::bad_cast
// if you try the wrong type
auto& safe_ref = dynamic_cast<Specific&>(GetGenericDataRef());
// unsafe, undefined behavior if it's the wrong type,
// but faster if it is
auto unsafe = static_cast<Specific*>(GetGenericData());
I assume here that your data is simple.
struct Generic {
int x=0;
int y=0;
};
struct Specific:Generic{
int z=0;
explicit Specific(Generic const&o):Generic(o){}
// boilerplate, some may not be needed, but good habit:
Specific()=default;
Specific(Specific const&)=default;
Specific(Specific &&)=default;
Specific& operator=(Specific const&)=default;
Specific& operator=(Specific &&)=default;
};
and bob is your uncle. It is somewhat important that int z hae a default initializer, so we don't have to repeat it in the from-parent ctor.
I made thr ctor explicit so it will be called only explicitly, instead of by accident.
This is a suitable solution for simple data.
So the first step is to realize you have a dynamic state problem. The nature of the state you store changes based off dynamic information.
struct GenericState { virtual ~GenericState() {} }; // data in here
struct Generic;
template<class D>
struct GenericBase {
D& self() { return *static_cast<D&>(*this); }
D const& self() const { return *static_cast<D&>(*this); }
// code to interact with GenericState here via self().pImpl
// if you have `virtual` behavior, have a non-virtual method forward to
// a `virtual` method in GenericState.
};
struct Generic:GenericBase<Generic> {
// ctors go here, creates a GenericState in the pImpl below, or whatever
~GenericState() {} // not virtual
private:
friend struct GenericBase<Generic>;
std::unique_ptr<GenericState> pImpl;
};
struct SpecificState : GenericState {
// specific stuff in here, including possible virtual method overrides
};
struct Specific : GenericBase<Specific> {
// different ctors, creates a SpecificState in a pImpl
// upcast operators:
operator Generic() && { /* move pImpl into return value */ }
operator Generic() const& { /* copy pImpl into return value */ }
private:
friend struct GenericBase<Specific>;
std::unique_ptr<SpecificState> pImpl;
};
If you want the ability to copy, implement a virtual GenericState* clone() const method in GenericState, and in SpecificState override it covariantly.
What I have done here is regularized the type (or semiregularized if we don't support move). The Specific and Generic types are unrelated, but their back end implementation details (GenericState and SpecificState) are related.
Interface duplication is avoided mostly via CRTP and GenericBase.
Downcasting now can either involve a dynamic check or not. You go through the pImpl and cast it over. If done in an rvalue context, it moves -- if in an lvalue context, it copies.
You could use shared pointers instead of unique pointers if you prefer. That would permit non-copy non-move based casting.
Ok, after some additional study, I am wondering if what is wrong with doing this:
struct Generic {}
struct Specific : Generic {
Specific( const Generic &obj ) : Generic(obj) {}
}
Correct me if I am wrong, but this works using the implicit copy constructors.
Assuming that is the case, I can avoid having to write one and does perform the casting automatically, and I can now write:
Specific s = GetGenericData();
Granted, for large objects, this is probably not a good idea, but for smaller ones, will this be a "correct" solution?

COM object releasing function gives error when passing a "IUnknown * &" as parameter

In a header, following code is included.
inline void SafeRelease( IUnknown * & in_COM_Pointer )
{
if ( NULL != in_COM_Pointer )
{
in_COM_Pointer->Release();
in_COM_Pointer = NULL;
}
}
When It is used as given below,
SafeRelease(_D3DDevice); // _D3DDevice is a "IDirect3DDevice9 *". According to documentation it is inherited from "IUnknown".
It gives a compilation error:
error C2664: 'SafeRelease' : cannot convert parameter 1 from
'IDirect3DDevice9 *' to 'IUnknown *&'
I know how to write this function using templates or macros. But I want to know why this happens.
Why does this give error?
How to write it correctly?
If inheritance cannot be used for writing this function should I use templates?
Anything that I would have to be careful about when implementing it using suggested method?
COM does not permit casting interface pointers, you must use QueryInterface(). This is enforced by the C++ compiler. Like this:
class Base {};
class Derived : /*public*/ Base {};
inline void SafeRelease(Base* & ptr) {}
void test() {
auto p = new Derived;
SafeRelease(p); // C2664
}
You can do it with a template function:
template<typename T>
inline void SafeRelease(T * & in_COM_Pointer) {
if (NULL != in_COM_Pointer) {
in_COM_Pointer->Release();
in_COM_Pointer = NULL;
}
}
Note: To fully grasp the information in this post, some knowledge about lvalues and rvalues is required.
Introduction
SafeRelease(_D3DDevice); // ill-formed
Here we try pass the address of a _D3DDevice to SetRelease, but it is not callable since it requires an lvalue (a reference to) of type pointer-to-IUnknown.
Just because Derived inherits from Base, does not mean that an lvalue pointer to Derived can be converted to an lvalue of type pointer to Base.
The implicitly conversion from Derived* to Base* will yield an rvalue.
struct A { };
struct B : A { };
void func (A*&);
B* p = ...;
func (ptr); // ill-formed, the implicitly yield `A*` is not an lvalue,
// and rvalues cannot bind to lvalues refernces
What is the "solution"?
inline void SafeRelease( IUnknown * in_COM_Pointer );
SafeRelease (&_D3DDevice); // (A)
(A) will yield a temporary of type pointer-to-IDirect3DDevice9, this pointer can implicitly turn into a pointer-to-IUnknown since IDirect3DDevice9 inherits from IUnknown.
We no longer try to form an lvalue-reference to the implicitly yield pointer, and the code compiles..
Implications
... but, this also means that we will be unable to update the value of any pointer argument passed in, so if that is an requirement you have/should resort to using templates so that you can get a reference to the actual value passed as argument.
template<typename T>
inline void SafeRelease(T * & in_COM_Pointer);
” 1. Why does this give error?
Consider this:
struct Animal {};
struct Dog: Animal { void bark() {} };
struct Dolphin: Animal { void dive() {} };
void foo( Animal*& p ) { p = new Dolphin(); }
auto main() -> int
{
Dog* p = new Dog();
foo( p ); //! C2664, Would have changed p to point to Dolphin.
p->bark(); // Uh huh...
}
So, this is not permitted.
There’s more of the same, e.g. regarding deep const-ness of actual versus formal argument, and it’s generally known as the Liskov Substitution Principle, the LSP, after Barbara Liskov.
” 2. How to write it correctly?
One solution for the general problem, as Hans Passant has already mentioned, is to use templating in order to deal directly with the type or types at hand, no conversion.
In this concrete case, however, as long as you’re sure that you don’t have a nullpointer, just call p->Release() instead of SafeRelease( p ).
” 3. If inheritance cannot be used for writing this function should I use templates?
You can use templating but it’s not necessary; see above.
” 4. Anything that I would have to be careful about when implementing it using suggested method?
The suggested method involves an envisioned implicit conversion Derived* → Base* for COM interface pointers.
Do note that while Derived* → Base* conversion generally works nicely also with COM interfaces, the IUnknown interface is subject to very special rules.
Namely, internally a COM object may have multiple IUnknown sub-objects, corresponding to possible IUnknown* pointers into this object, but only one of these pointer values identifies the object.
So when you want an IUnknown pointer that identifies the object, a pointer that can be compared to other IUnknown pointers to check if it’s the same object, you have to use QueryInterface to obtain the IUnknown pointer.
Happily you can use QueryInterface via any interface pointer that you have, and since this member function is provided via the IUnknown interface that all other interfaces inherit, it illustrates that you can use non-identifying IUnknown pointers for other purposes than identification.
IDirect3DDevice9 is inherited from IUnknown but it is not exactly IUnknown. This makes IDirect3DDevice9* variable incompatible with IUnknown*& argument.
Hence, you need to either cast between types, or use a more flexible releasing function, template based, e.g.:
template <typename IFoo>
VOID SafeRelease(IFoo*& pFoo)
{
if(!pFoo)
return;
pFoo->Release();
pFoo = NULL;
}
IDirect3DDevice9* pDevice = ...
...
SafeRelease(pDevice);
Or rather, and it's serious improvement in development accuracy, use template wrappers over raw interface pointers, such as CComPtr.
CComPtr<IDirect3DDevice9> pDevice = ...
...
pDevice.Release(); // or pDevice = NULL,
// or nothing - automatic release on going out of scope

Using RTTI to determine inheritance graph in C++?

What, if any, c++ constructs are there for listing the ancestors of a class at runtime?
Basically, I have a class which stores a pointer to any object, including possibly a primitive type (somewhat like boost::any, which I don't want to use because I need to retain ownership of my objects). Internally, this pointer is a void*, but the goal of this class is to wrap the void* with runtime type-safety. The assignment operator is templated, so at assignment time I take the typeid() of the incoming pointer and store it. Then when I cast back later, I can check the typeid() of the cast type against the stored type_info. If it mismatches, the cast will throw an exception.
But there's a problem: It seems I lose polymorphism. Let's say B is a base of D. If I store a pointer to D in my class, then the stored type_info will also be of D. Then later on, I might want to retrieve a B pointer. If I use my class's method to cast to B*, then typeid(B) == typeid(D) fails, and the cast raises an exception, even though D->B conversion is safe. Dynamic_cast<>() doesn't apply here, since I'm operating on a void* and not an ancestor of B or D.
What I would like to be able to do is check is_ancestor(typeid(B), typeid(D)). Is this possible? (And isn't this what dynamic_cast<> is doing behind the scenes?)
If not, then I am thinking of taking a second approach anyway: implement a a class TypeInfo, whose derived classes are templated singletons. I can then store whatever information I like in these classes, and then keep pointers to them in my AnyPointer class. This would allow me to generate/store the ancestor information at compile time in a more accessible way. So failing option #1 (a built-in way of listing ancestors given only information available at runtime), is there a construct/procedure I can use which will allow the ancestor information to be generated and stored automatically at compile-time, preferably without having to explicitly input that "class A derives from B and C; C derives from D" etc.? Once I have this, is there a safe way to actually perform that cast?
I had a similar problem which I solved through exceptions! I wrote an article about that:
Part 1, Part 2 and code
Ok. Following Peter's advise the outline of the idea follows. It relies on the fact that if D derives from B and a pointer to D is thrown, then a catch clause expecting a pointer to B will be activated.
One can then write a class (in my article I've called it any_ptr) whose template constructor accepts a T* and stores a copy of it as a void*. The class implements a mechanism that statically cast the void* to its original type T* and throws the result. A catch clause expecting U* where U = T or U is a base of T will be activated and this strategy is the key to implementing a test as in the original question.
EDIT: (by Matthieu M. for answers are best self-contained, please refer to Dr Dobbs for the full answer)
class any_ptr {
void* ptr_;
void (*thr_)(void*);
template <typename T>
static void thrower(void* ptr) { throw static_cast<T*>(ptr); }
public:
template <typename T>
any_ptr(T* ptr) : ptr_(ptr), thr_(&thrower<T>) {}
template <typename U>
U* cast() const {
try { thr_(ptr_); }
catch (U* ptr) { return ptr; }
catch (...) {}
return 0;
}
};
The information is (often) there within the implementation. There's no standard C++ way to access it though, it's not exposed. If you're willing to tie yourself to specific implementations or sets of implementations you can play a dirty game to find the information still.
An example for gcc, using the Itanium ABI is:
#include <cassert>
#include <typeinfo>
#include <cxxabi.h>
#include <iostream>
bool is_ancestor(const std::type_info& a, const std::type_info& b);
namespace {
bool walk_tree(const __cxxabiv1::__si_class_type_info *si, const std::type_info& a) {
return si->__base_type == &a ? true : is_ancestor(a, *si->__base_type);
}
bool walk_tree(const __cxxabiv1::__vmi_class_type_info *mi, const std::type_info& a) {
for (unsigned int i = 0; i < mi->__base_count; ++i) {
if (is_ancestor(a, *mi->__base_info[i].__base_type))
return true;
}
return false;
}
}
bool is_ancestor(const std::type_info& a, const std::type_info& b) {
if (a==b)
return true;
const __cxxabiv1::__si_class_type_info *si = dynamic_cast<const __cxxabiv1::__si_class_type_info*>(&b);
if (si)
return walk_tree(si, a);
const __cxxabiv1::__vmi_class_type_info *mi = dynamic_cast<const __cxxabiv1::__vmi_class_type_info*>(&b);
if (mi)
return walk_tree(mi, a);
return false;
}
struct foo {};
struct bar : foo {};
struct baz {};
struct crazy : virtual foo, virtual bar, virtual baz {};
int main() {
std::cout << is_ancestor(typeid(foo), typeid(bar)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(baz)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(int)) << "\n";
std::cout << is_ancestor(typeid(foo), typeid(crazy)) << "\n";
}
Where I cast the type_info to the real type that's used internally and then recursively used that to walk the inheritance tree.
I wouldn't recommend doing this in real code, but as an exercise in implementation details it's not impossible.
First, what you are asking for cannot be implemented just on top of type_info.
In C++, for a cast to occur from one object to another, you need more than blindly assuming a type can be used as another, you also need to adjust the pointer, because of multi-inheritance (compile-time offset) and virtual inheritance (runtime offset).
The only way to safely cast a value from a type into another, is to use static_cast (works for single or multi-inheritance) and dynamic_cast (also works for virtual inheritance and actually checks the runtime values).
Unfortunately, this is actually incompatible with type erasure (the old template-virtual incompatibility).
If you limit yourself to non-virtual inheritance, I think it should be possible to achieve this by storing the offsets of conversions to various bases in some Configuration data (the singletons you are talking about).
For virtual inheritance, I can only think of a map of pairs of type_info to a void* (*caster)(void*).
And all this requires enumerating the possible casts manually :(
It is not possible using std::type_info since it does not provide a way to query inheritance information or to convert a std::type_info object to its corresponding type so that you could do the cast.
If you do have a list of all possible types you need to store in your any objects use boost::variant and its visitor.
While I can't think of any way to implement option #1, option #2 should be feasible if you can generate a compile-time list of the classes you would like to use. Filter this type list with boost::MPL and the is_base_of metafunction to get a list of valid-cast typeids, which can be compared to the saved typeid.

C++ A polymorphic class, virtual function and casting for performance

I have the following classes:
class State
{
protected:
Vec3D accel;
Vec3D gyro;
Vec3D gps;
float reward;
public:
boost::ptr_vector<Action> actions;
...
virtual bool isTerm();
}
class guState : public State
{
float gps_stand_thres;
float gps_down_thres;
public:
guState(Agent &A,ACTION_MODE &m);
bool isTerm();
};
There are other classes which all inherit from State. Their differences solely lie on how they evaluate isTerm() which depends on behavior.
I would rather not use virtual functions bur override function isTerm, if it wasn't for the fact that there are a few other templated classes which are designed to work with all sorts of State-derived classes.
One of them is Policy:
template <class S>
class Policy
{
protected:
float QValue;
S *state;
S *nextState;
public:
...
template <class P>
void updateOptimal(boost::ptr_vector<P> &policies);
}
updateOptimal has to obtain A State-derived class (depending on behavior), up-cast from a State *ptr to whatever the S-type being currently used is, in order to search for policies for that state. Now, because State-derived classes are polymorphic, I assumed it was the right thing to do:
S *s = dynamic_cast<S *>(iter->getNextState());
where the iter is an iterator of Actions and each action has a pointer of State *nextstate;
action->nextstate is set at some other point:
action->setNextState(dynamic_cast<State *>(state));
I could template the entire class Action, in order to avoid using State *nextstate; and use S *nextstate; but that would require an enormous amount of changes throughout the project.
Reading the casting tutorial on cplusplus.com it is my understanding that it is best to use dynamic_cast because it does a type check before up or down casting.
However in the following code after casting I do not do anything to the up casted state other than use it for searching:
P *temp_pol = var::findPolicy(policies,s);
where findPolicy is:
template <class P, class S>
P* findPolicy(boost::ptr_vector<P> &policies,S *state);
Would it be ok to skip safety checks, and use a static cast ? I
have tried it, and it compiles.
Would it be ok to skip checks altogether, and do a reinterpret_cast ?
I have also tried it and it compiles.
What is the penalty for doing a dynamic_cast ? I know theres a small
overhead, but is it anything serious ?
Is there a way to upcast from State *ptr to S-type *ptr without using
a polymorphic class (avoiding the virtual function and simply
override it)?
The difference between static_cast and dynamic_cast is that an invalid static_cast is undefined behavior, while an invalid dynamic_cast results in a null-pointer or a bad_cast-exception (if you cast references). The penalty for a dynamic_cast is a type-check during runtime, and increased code-size due to RTTI.
So, if you are sure that the cast is always fine, you can safely use static_cast. Using reinterpret_cast would not give you any performance-improvement over static_cast, so you shouldn't use it here.

Check if a ptr belongs to a virtual class?

My code was acting wonky and i was able to mini reproduce it with the code below. (codepad link)
From http://www.cppreference.com/wiki/keywords/dynamic_cast
If you attempt to cast to a pointer
type, and that type is not an actual
type of the argument object, then the
result of the cast will be NULL.
From my understanding this_test should be null. It isnt. How do i check if that dummy ptr is actually a ptr to a dummy object?
#include <ios>
struct Dummy{ virtual void dummyfn(){} };
int main(){
Dummy* this_test = dynamic_cast<Dummy*>((Dummy*)0x123);
//assert(this_test==0);
cout << std::hex << this_test<<endl;
return 0;
}
output:
0x123
Wishful thinking... :)
I believe dynamic_cast only works for downcasts in polymorphic cases, not any cast whatsoever. It's not like the compiler stores type information for every single variable, so it can't do what you're thinking -- I'm pretty sure it's undefined behavior.
The issue is that dynamic_cast expects either:
a null pointer
a valid pointer
Here you can only offer it garbage, so it is useless, and not the cast you want.
If you are getting a void*, then you can use reinterpret_cast (better than a C-cast, because more visible) to cast it into another type:
void* p = 0x123;
Dummy* dummy = reinterpret_cast<Dummy*>(p);
Note: the presence or absence of virtual methods goes unnoticed here
EDIT: if you can modify the objects being passed...
Then try to use a common base class:
struct Base: private boost::noncopyable { virtual ~Base() = 0 }; Base::~Base() {}
And define the following helpers:
template <typename T>
void* to_void(T* t) {
Base* base = t;
return reinterpret_cast<void*>(base);
}
template <typename T>
T* from_void(void* p) {
Base* base = reinterpret_cast<Base*>(p);
return dynamic_cast<T*>(base);
}
The former is extremely important because of the possible pointer adjustment (which will probably only occur in the case of Multiple Inheritance).
Note: it's possible to use a fast_cast here if you don't use virtual inheritance or other RTTI stuff
template <typename T, typename U>
T* fast_cast(U* u) {
#ifdef NDEBUG
return static_cast<T*>(u);
#else
return dynamic_cast<T*>(u);
#endif
}
If this is not possible the following solutions are possible, but they are going to feel hacky I fear.
Since dynamic_cast is not going to work properly here, you have to actually come up with your own type checking mechanism.
One method could be to use a "repository" in which you register the void* pointers you get, and the associated type_info object.
typedef std::map<void*, std::type_info const*> Repository;
template <typename Dest>
Dest* dynamic_check(void* p, Repository const& rep) {
Repository::const_iterator it = rep.find(p);
assert(it != rep.end() && "dynamic_check: no such entry");
assert(typeid(Dest) == *(it->second) && "dynamic_check: wrong type");
return reinterpret_cast<Dest*>(p);
}
If this is not possible, then you could hack the C++ object model to your advantage. If you know that the object has at least one virtual method, then it necessarily has a virtual pointer on all compilers I know (VS, gcc, clang), and this pointer is the first 4/8 bytes of the object.
inline void* virtual_pointer(void* p) {
assert(p != 0 && "virtual_pointer: null");
return reinterpret_cast<void*>(*p);
}
template <typename T>
void* virtual_pointer(T const& t) {
return virtual_pointer(reinterpret_cast<void*>(&t));
}
template <typename T>
void* virtual_pointer() {
static void* pointer = virtual_pointer(T());
return pointer;
}
template <typename Dest>
Dest* dynamic_check(void* p) {
assert(virtual_pointer<Dest>() == virtual_pointer(p));
return reinterpret_cast<Dest*>(p);
}
Note: both solutions suffer from the same shortcoming, they will only work if you precise the exact type (well, you could get away with it as long as two types share the same virtual table, which happens if a derived class does not override any virtual method, including the destructor).
This is far from the power of a true dynamic_cast.
You skipped one sentence from your quote:
The dynamic_cast keyword casts object from one pointer or reference type to another, performing a runtime check to ensure the validity of the cast.
The problem here is that 0x123 isn't a pointer to an object, so it just doesn't work.
Actually dynamic_cast only works on polymorphic types (usually this means they must have a vtable). Since you're using a C-cast to assert to the compiler that the type is Dummy*, it believes you. Since you're then doing an identity dynamic_cast on a random memory location it doesn't/isn't able to do the type checking.
But seriously, 99% of the time don't try to test that something is a particular type. Design your classes such that the base classes define an interface and the child classes implement it, allowing use without lots of casting (which is a design smell).
dynamic_cast does not perform any run-time checking when you use it for upcasts or identity-casts (casts to the same type). For such casts dynamic_cast behaves exactly the same as an ordinary static_cast. No difference whatsoever.
The page you linked does not mention that, i.e. is not even a remotely complete specification of dynamic_cast, which makes it pretty useless.
C++ provides no means to determine whether a given pointer is actually a valid pointer to a given type. So, you are out of luck there. Implement your own checking method.