On Thu, Aug 31, 2006 at 02:29:04AM +0200, Roland Mainz wrote:

> BTW: Would it be possible to get the following two macros (and derivates
> for |unsigned long|) into OS/Net ? IMO they should provide a quite clean
> way to do such conversions and would provide an easy way to search for
> such stuff:
> -- snip --
> #define UTS_LONG_TO_PTR(l) ((void*)((char*)0 + (l)))
> #define UTS_PTR_TO_LONG(ptr) ((long)((char *)(ptr) - (char *0)))
> -- snip --

This doesn't solve the problem; the interesting case is a 32-bit
integer casted to a pointer (or a 64-bit integer casted to a 32-bit
pointer; the exact combinations that cause problems depend on how
you're compiling).  You could do something like

#define UTS_TO_POINTER(x) ((void *)(uintptr_t)(x))

But that saves you very little, and also implies that this cast is
invariably safe and correct, which it is not.  If the argument to the
macro is actually a signed type, sign extension will be performed by
the cast to uintptr_t, which may or may not be desired - that is, the
original variable may be signed because it really is signed or it may
be signed because it comes from some other type that just happens to
be defined that way.  Basically, you have to know whether you want
sign- or zero-extension and cast appropriately.  Going the other way,
you may want to cast the pointer to a signed or unsigned 32- or 64-bit
quantity.  Of course, more macros could be written to address every
possibility, or a single pair of extremely complex macros using
__typeof() could be written, but in neither case would the macros do
much to improve readability, save typing, or reduce the incidence of
programmer error.

If you want to solve this problem in a useful way, change the compiler.

-- 
Keith M Wesolowski              "Sir, we're surrounded!" 
FishWorks                       "Excellent; we can attack in any direction!" 
_______________________________________________
tools-discuss mailing list
tools-discuss@opensolaris.org

Reply via email to