2

I am using Tcl_CreateObjCommand(interp, cmdName, proc, clientData, deleteProc) in my code and passing in a DerivedClass pointer to the clientData parameter. In the callback function, I want to type safe convert (dynamic_cast) the clientData back to the DerivedClass pointer, but the gcc compiler is complaining "source is not a class to pointer". This is because the clientData is a type of void pointer. In this use case, how would developers usually handle this issue when using Tcl API?

int main()
{
  ...
  Tcl_CreateObjCommand(interp, cmdName, myCallback, myDerivedClassPointer, (Tcl_CmdDeleteProc *)NULL);
}

myCallback(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj* const objv[])
{
  // I want to do something like this, so when the pointer is not a DerivedClassPointer type, throw an exception.
  DerivedClass* foo = dynamic_cast<DerivedClass*>(clientData);  
  if(!foo) throw exception, type conversion fail
}
Johannes Kuhn
  • 14,778
  • 4
  • 49
  • 73
Stan
  • 37,207
  • 50
  • 124
  • 185
  • 1
    See [dynamic_cast from “void *”](http://stackoverflow.com/questions/4131091/dynamic-cast-from-void), you can't do it. Use `static_cast`, see [this question](http://stackoverflow.com/questions/310451/should-i-use-static-cast-or-reinterpret-cast-when-casting-a-void-to-whatever). – Peter Wood Jun 15 '13 at 19:47
  • I know this, thanks. But there are cases in the runtime, a non-DerivedClassPointer would be passed into the callback function and causes segmentation fault. So I want to do the safe conversion if possible. – Stan Jun 15 '13 at 19:57
  • 2
    You control the client. Only pass one common type of client data to the callback, then you can't mistakenly cast it to the wrong type when you use `static_cast`. If you want polymorphism, have the common type delegate to a polymorphic object. – Peter Wood Jun 15 '13 at 21:30

1 Answers1

0

As @PeterWood said: this is impossible. Furthermore, it is a bug that any invalid pointers got passed to Tcl_CreateObjCommand in the first place.

The correct way (again as @PeterWood states) is to ensure that the ClientData you receive is always valid. The best way to do this is with a template function that checks (at compile-time) that the types are correct.

Demi
  • 3,535
  • 5
  • 29
  • 45