0

An interface limitation forces me to cast MyObject* into a void* using static_cast. When getting this pointer back on later interface calls, I have to perform another static_cast from void* to MyObject*, because dynamic_cast wouldn't work in this case (explained here).

However, I'd like to perform a type-safety check, to ensure no weird things happen if somebody else changes parts of the code. If there is any check that can be performed under this circumstands, which one would be the best/most convenient one?

Community
  • 1
  • 1
Migsi
  • 107
  • 2
  • 10
  • No, you don't have to use a `static_cast` to convert a `MyObject*` into a `void*`. That's an implicit conversion. Yes, you do have to use a `static_cast` to get back from that `void*` to your `MyObject*`. – Pete Becker Jan 30 '17 at 15:40
  • Code comments showing the link between the callback submission and the callback function are usually enough to remind maintainers to update type information. If people get it wrong a lot in your code, write scripts to run during build to verify matching types. – Zan Lynx Jan 30 '17 at 16:19
  • You can also use the type system to help guarantee this, by creating a typedef for each callback and using that on both sides. Suppose you have a `async_lookup` function, you could declare a `typedef DictionaryEntry async_lookup_cb_type` – Zan Lynx Jan 30 '17 at 16:24
  • @ZanLynx It's a rare occasion I have to void* cast something in our code (and cast it back to its initial type). So there is almost no possibility someone will get it wrong. Regarding your typedef idea, could you please provide a more precise example? – Migsi Feb 01 '17 at 08:23
  • 1
    @Migsi: I don't want to write a code sample. Just use the typedef on the sending and receiving sides of the interface, so that if the type is ever changed, changing the typedef automatically changes it in all places. – Zan Lynx Feb 01 '17 at 17:55

1 Answers1

1

No, once you hit void* it's all up to the code to get casts right. The root cause is that the void* you get back theoretically can point to almost anything: a char, int, std::string, std::complex<double>, std::map<int, int>::iterator and of course MyObject.

The problem you'll face is that your cast will only work if the void* actually points to a MyObject, but in that case the cast wasn't necessary anyway.

A non-casting workaround is to keep a std::unordered_set<void*> of all the void* you created by casting MyObject*, removing expired pointers via ~MyObject(), and checking that set before casting.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • You are clearly right about this, but isn't there any way to perform a type check after the static_cast from `void*` to `MyObject*`? In genral, that means I'd need to check if an Object really has the type it seems to have. – Migsi Jan 31 '17 at 08:27
  • 1
    @Migsi: No. There are 3 cases to consider: check passed, check failed, Undefined Behavior. Trying a `static_cast` can only result in a check passed or UB, and once you hit UB you can't undo that. So the "check failed" result is impossible. – MSalters Jan 31 '17 at 09:42