tags:

views:

55

answers:

4

Hi all,

My application uses an int as id to identify objects in both in-memory and persistent registry. Functions in the application receive the id as argument, retrieve the object from the registry and do their job, e.g.

void print( int id, int bar, double zip, int boo )
{
    Object *obj = get_obj_by_id( id );
    obj->print( bar, zip, boo );
}

The application has evolved and now it is possible to have more than one registry in the same application. The application now uses a globally accessible 'current' registry, which, as globals tend to do, causes a lot of trouble.

To get rid of the concept of a global 'current' registry, I would need to introduce a type that uniquely identifies the object across registries. I cannot change the value of the int that is being used, so I have to create a full_id type from the int id and an identification of the registry. The example function hence would have to change to

void print( full_id id, int bar, double zip, int boo )
{
    Object *obj = get_obj_by_id( id );
    obj->print( bar, zip, boo );
}

There are conventions about the naming of id arguments, but these are not rigorously followed throughout the application, so I cannot make assumptions about the name of the id argument, or that it is always the first argument. Also there are many many functions that that have to be changed. What is the most efficient and reliable way to replace the int typed ids by full_id typed ids?

A: 

I would start looking for all calls to get_obj_by_id and change its argument from int to full_id. Then compile, and see what doesn't compile, and repeat this iteratively until you found all places. Slow, but it will work.

Patrick
+4  A: 

Presumably your new type isn't numeric - it's something like a small struct?

typedef struct _full_id {
    int registry_id;
    int object_id;
} full_id;

If so, then you can just start by changing your low-level functions that deal with IDs - like the get_obj_by_id() function in your example. After you change that function to take a full_id parameter instead of an int, recompile the complete program. All the call sites that call this function should now report an error due to the type mismatch - you can then go to those call sites and fix their parameter types.

Rinse, repeat, and eventually you'll have fixed them all.

Good luck (and I bet you wish you'd used a typedef to begin with, now? ;)

caf
+1 for mentioning that a typedef would have solved the problem much easier.
Patrick
+1  A: 

The most reliable way: make sure you can't implicitly convert an int to full_id. Then change the argument to get_obj_by_id to a full_id, and let the compiler work out where you need to change things.

It's rather inefficient, but very reliable (except for human errors)..

Jan
A: 

If you have control over ID allocation, you could allocate a certain range of IDs for certain registries and in get_obj_by_id() to decide which registry to address.

Example:

Object* get_obj_by_id(int id)
{
    if( id % 2 )
        return registry1[id];
    else
        return registry2[id];
}
Dmitry Yudakov