Re: Trick to prevent conversion
On Fri, 11 Jan 2008 19:18:05 GMT, "Tom1s # hilidhe" <toe@lavabit.com>
wrote in comp.lang.c++:
(I'm simplifying this problem greaty in the following code but you get
the idea)
I have a class something like:
class Processor {
public:
unsigned GetCurrentProcess(void);
unsigned GetCurrentThread(void);
void DoSomethingWithProcess(unsigned process_id);
void DoSomethingWithThread(unsigned thread_id);
};
The function, GetCurrentProcess, returns an unsigned integer value
which represents a process.
The function, GetCurrentThread, returns an unsigned integer value
which represents a thread.
The problem is, that it's very easy to mistakenly take the value from
GetCurrentProcess and pass it as an argument to DoSomethingWithThread.
(I've done it already!). Therefore, I want two different types for these
identifiers, two types that can't convert to each other. At the moment I
have the following:
class Processor {
public:
struct ProcessHandle { unsigned i; };
struct ThreadHandle { unsigned i; };
ProcessHandle GetCurrentProcess(void);
ThreadHandle GetCurrentThread(void);
void DoSomethingWithProcess(ProcessHandle process_id);
void DoSomethingWithThread(ThreadHandle thread_id);
};
Of course, this does the trick. But I'm wondering if there's a more
elegant way of doing it? What other methods are there for making types
incompatible with each other?
(My actual code is far more complicated than this -- obviously I wouldn't
be very competant if I made such a stupid mistake in code as simple as
this).
Why not two enumeration types, suitably defined so that hold the value
range you want, i.e.:
enum process_id { process_id_min = 0, process_id_max = UINT_MAX };
enum thread_id { thread_id_min = 0, process_id_max = UINT_MAX };
Modify your functions to accept and receive the enumerated types, with
suitable static_casts to and from unsigned int, as needed, inside the
functions, invisible to the caller. Modify your callers who get the
values to accept the appropriate enumeration type.
A C++ compiler will reject code where a caller retrieves a process_id
from one function and attempts to pass it to another that needs a
thread_id.
I even use this technique in C, where any decent compiler will warn
about mixing different enumeration types even though the language
permits it.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html