views:

257

answers:

3

I inherited a big application that was originally written in C (but in the mean time a lot of C++ was also added to it). Because of historical reasons, the application contains a lot of void-pointers. Before you start to choke, let me explain why this was done.

The application contains many different data structures, but they are stored in 'generic' containers. Nowadays I would use templated STL containers for it, or I would give all data structures a common base class, so that the container can store pointers to the base class, but in the [good?] old C days, the only solution was to cast the struct-pointer to a void-pointer.

Additionally, there is a lot of code that works on these void-pointers, and uses very strange C constructions to emulate polymorphism in C.

I am now reworking the application, and trying to get rid of the void-pointers. Adding a common base-class to all the data structures isn't that hard (few days of work), but the problem is that the code is full of constructions like shown below.

This is an example of how data is stored:

void storeData (int datatype, void *data);    // function prototype
...
Customer *myCustomer = ...;
storeData (TYPE_CUSTOMER, myCustomer);

This is an example of how data is fetched again:

Customer *myCustomer = (Customer *) fetchData (TYPE_CUSTOMER, key);

I actually want to replace all the void-pointers with some smart-pointer (reference-counted), but I can't find a trick to automate (or at least) help me to get rid of all the casts to and from void-pointers.

Any tips on how to find, replace, or interact in any possible way with these conversions?

A: 

You probably don't need to get rid of the casts to use shared pointers.

storeData(TYPE_CUSTOMER, myCustomer1->get());

shared_ptr<Customer> myCustomer2(reinterpret_cast<Customer*>fetchData(TYPE_CUSTOMER, "???");

Of course, this assumes that you don't expect to share the same pointer across calls to store/fetch. In other words, myCustomer1 and myCustomer2 don't share the same pointer.

Noah Roberts
+6  A: 

I actually want to replace all the void-pointers with some smart-pointer (reference-counted), but I can't find a trick to automate (or at least) help me to get rid of all the casts to and from void-pointers.

Such automated refactoring bears many risks.

Otherwise, sometimes I like to play tricks by making out of such void* functions the template functions. That:

void storeData (int datatype, void *data);

becomes:

template <class T>
void storeData (int datatype, T *data);

At first implement template by simply wrapping the original (renamed) function and converting the types. That might allow you to see potential problems - already by simply compiling the code.

Dummy00001
A: 

Apparently, there is no automated way/trick to convert or find all uses of void-pointers. I'll have to use manual labor to find all void-pointers, in combination with PC-Lint that will give errors whenever there is an incorrect conversion.

Case closed.

Patrick