views:

52

answers:

4

I'm porting some old C++ project on Linux (RHEL 5.3).

The situation is the following

#include <semaphore.h>

class OldClass: public sem_t

This used to work because till glibc-2.3.3.20040420 sem_t was a struct. Now, with the newer version of glib is a union =>inheritance not allowed. so the compilation doesn't work.

how it was:

typedef struct { struct
_pthread_fastlock __sem_lock;  
int __sem_value;
_pthread_descr __sem_waiting; }  
sem_t;

how it is:

typedef union { 
char __size[__SIZEOF_SEM_T]; 
long int __align; } 
sem_t;

What would be the best approach to fix this?How can I "wrap" the functionality of sem_t?

Many thanks!

======later edit====================================

OldClass is "later" used by some other class (project is quite big) : therefore, I'm looking for a way to keep the same interface, so I can avoid re-writing all the calls to OldClass.

I was thinking if there a way to create a class MySem_t that wraps around sem_t;OldClass would then inherit MySem_t... does this sound feasible?

Thank you.

+1  A: 

Inheriting from sem_t was never intended, so the code you're porting clearly had some issues if they chose to inherit rather than storing a separate semaphore.

Rather than trying to duplicate the way the old code approaches the problem, I would suggest you do some analysis and refactor such that OldClass doesn't inherit from sem_t, but uses a sem_t where necessary.

I know nothing about the code so I can't direct you further, but that's probably your best attack vector.

Randolpho
+1  A: 

What exactly is the purpose of inheritance here? If you're just after syntactic sugar of method syntax (think extension methods in .Net), then you should probably just use free functions.

If you actually need the separate class, then you should favor composition over inheritance. I.e. OldClass should have a sem_t member, not be a sem_t.

Cogwheel - Matthew Orlando
+4  A: 

You have to create a class member with type sem_t. To simplify porting, you can use type cast methods like this:

class MyClass {
  private:
    sem_t _sem;
  public:
    operator sem_t&() { return _sem; }
    operator const sem_t&() const { return _sem; }
// etc
}
grep
+1 given original question's edit
Cogwheel - Matthew Orlando
Sounds very nice.Thanks.Would it make sense to go in this direction class OldClass : public MyClass ...I wonder if I need other operators that I should overload?Thank you.
silver77
You should just be able to add these members to OldClass directly.
Cogwheel - Matthew Orlando
A: 

Take the definition OldClass, and rewrite it, with OldClass having a sem_t. Don't worry about it being a good rewrite, although you want the definition itself to compile. Now, try recompiling. Be prepared for cascades of error messages, because it's likely that the code was using OldClass as a simple struct. Go through the mass of error messages.

If you're lucky, not a whole lot of code messed with the sem_t members directly, because you will have to change each one of those lines. (You'd have had to change them anyway, even without the infelicitous inheritance, since sem_t changed fundamentally.) Unfortunately, programmers who thought it a good idea to inherit from sem_t likely didn't think it necessary to treat sem_t as an opaque data type, to be used as a whole except for certain functions.

David Thornley