See this GTK callback function:
static gboolean callback(GtkWidget *widget, GdkEventButton *event, gpointer *data)
{
AnyClass *obj = (AnyClass*) data;
// using obj works
}
(please note the gpointer* on the data). And then the signal is connected using:
AnyClass *obj2 = new AnyClass();
gtk_signal_connect(/*GTK params (...)*/, callback, obj2);
See that the *AnyClass is going to be cast to gpointer* (void**). In fact, this is working now. The callback prototype in GTK documentation is “gpointer data” and not “gpointer *data” as shown in code, what I want to know is: how this can work ? Is this safe ?
It’s not exactly safe, especially since in using c-style casts you’ve gone from doing a static_cast from T1* to void*, to a reinterpret_cast from T1* to void**. However, it works because the standard guarantees that you can reinterpret_cast from T1* to T2* (in this case T2=void*) and back again to get the same T1* you started with….IFF alignment requirements of T1* and T2* are the same.
In other words, it will work on most implementations. The cast to/from void* is guaranteed but I don’t know that there are any requirements for a void**.
Doing a reinterpret_cast is always kind of risky. You have to get the T1 exactly right on both sides and the compiler has no way of helping you if you get it wrong. For example, if you cast from class T5, which is a subclass of T1, and then on the other side cast to a T1*…you could be totally screwed. The static_cast would have accounted for this I believe but a reinterpret_cast will not. It could work just fine until someone uses multiple inheritance on T5 for whatever reason.
You’re not gaining anything by adding the * to the hiding type. You should consider not doing it this way.
NOTE: my answer is regarding the C++ language. You tagged your question as both so you’re bound to get answers for both and they’re going to be very different.