> Patrik Stridvall <ps(a)leissner.se> writes:
>
> > Does the Windows API really define exactly what a handle is?
>
> typedef void* HANDLE seems pretty clear to me.
I was refering some documentation that said that
application should always expect a handle to be
a pointer.
But never mind. Documentation and reality is often
different things.
> > However your suggestion that any Winelib application that
> cares whether
> > they are 32-bit or 64-bit are broken is a far too strict
> IMHO and I see
> > no reason to require porters to fix such things.
>
> An application that assumes that everything is 32-bit is broken, yes.
> I don't see why handles are any different than other types; if
> anything they should be less of a problem since they are supposed to
> be opaque, so their size should not matter for the application.
>
> Of course most handles will fit in 32-bit, so we will still support
> apps that do invalid casts and truncate the handles; but this doesn't
> mean it is correct behavior, or that apps that do this should be able
> to compile without warnings.
OK, since you agree we should accept handles truncated to 32-bit,
it still leaves the problem. Should API calls truncate the handles
themselves ie take 32-bit integers as arguments or should they not
ie take 64-bit pointers as arguments.
There is no particular reason to not accept both and make the
actual definition of handle be dependent on some define
and leave the choice on whether they want warnings or not
to the Winelib developers, not leave them without a choice.
Actually we might also consider giving them the option to
accept 64-bit integers.
In short, the Winelib developers should decide what their
application wants (warning wise), we shouldn't.
> > So therefor I suggest that we should do the following
> > TRACE("(%p)", (LPVOID) handle);
>
> You must be joking.
No, I'm not. However reality forced me to change the
solution somewhat. See below.
> I said I didn't want any typecast, and here you
> suggest to have one on every single debugging output.
Well, we have (or should have) a debugstr_[aw]n? on every single
string in the debugging output, because we have to. We might not like it,
but we have it because we must.
> Let me repeat it
> once more just in case: *NO* *TYPECASTS*.
I know that you said that and I have said that I support that whenever
possible, which it fortunately is in the normal cases.
> The whole point of STRICT and pointer handles is to be able to use
> compiler type checks, and this is only possible without typecasts.
Agreed, but there is no self value in having no exceptions on a rule.
Remember no type cast is a means no a goal.
Debugging output is hardly a critical piece of code so if we can
gain something from it we should consider making an exception.
But never mind, it turns out that we we needn't make a exception
either. See below.
> Not
> to mention that your solution will probably still get a warning like
> "converting integer to pointer of different size" on a 64-bit
> platform.
Ah, thats a good point. Practice often stand in the way of a good theory.
:-(
Unfurtunately I think you are right, it is more than probable that the
compiler
will generate such a warning, I if not now so sometime in the future.
Casting to a 32-bit integer to 64-bit pointer is almost always bogus,
so there is no reason for the compiler not give a warning epecially
since you can do a double cast (32-bit integer to 64-bit integer to
64-bit pointer) if you really mean it.
Fortunately the problem is solvable
#ifdef __alpha__
#ifdef STRICT
#define HANDLE2POINTER(handle) (handle)
#else
#define HANDLE2POINTER(handle) ((void *) (unsigned long) (handle))
#endif
#ifdef STRICT
#define HANDLE2POINTER(handle) (handle)
#else
#define HANDLE2POINTER(handle) ((void *) (handle))
#endif
#endif
TRACE("(%p)", HANDLE2POINTER(handle));
This solves your problem (at least for 32-bit developers)
< The whole point of STRICT and pointer handles is to be able to use
< compiler type checks, and this is only possible without typecasts.
Francois problem
< * Ignore gcc's warnings saying '%x format, pointer argument'. Fixing the
format
< at this stage would only introduce tons of warnings for the developpers
not
< participating in the switch (i.e. compiling with STRICT off).
as well as my problem.
Of course we might consider making it a debug output only construct instead
Like s/HANDLE2POINTER/debugptr_handle/ and define it in debugtools.h.
Non-debugging parts of Wine shouldn't need to use it either since as I said
earlier just pass them long or must use an explict cast to a non-void
pointer.
Ah, wait a minute we will have "converting integer to pointer of different
size"
on 64-bit platforms for the actual cast to an object.
Of course easily solved with a similar
#ifdef __alpha__
#define HANDLE2OBJECT(type, handle) ((type *) (unsigned long) (handle))
#else
#define HANDLE2OBJECT(type, handle) ((type *) (handle))
#endif
but perhaps we should have the HANDLE2POINTER (debugptr_handle) in
debugtools.h all the same, nobody else is intrested in a void pointer
anyway.
Of course, nothing forces us to define handles as the same both
internally and externally. At least Alpha AFAIK will be binary
compatible all the same, so we might not even need this.
Oh well having to always using HANDLE2OBJECT is a small price
to pay all the same and makes it possible for us to do
adjustments on other 64-bit platforms if need be.
And yes, I'm serious. My inital solutions wasn't so good,
but thanks to your feedback I have managed to refine it to
a much better solution, that I think actually works in reality.
And yes, I still consider the 64-bit problem a real problem,
you just tries to dismiss the problem by simply saying,
that is the Winelib developers problem. Sure we could do
that but, remember that Winelib is meant to help developers
port application not make it more difficult by trying
to enforce unnessary restriction on the code.
Sure Win64 should use 64-bit pointers as handles that is
without questions, but forcing it on Win32 on 64-bit
is totally unnessary, especially since I now finally
after your feedback managed to find a solution that
solve all your stated problems (remember that no type
casts is a means not a goal and actually there will be
no type casts on 32-bit (-DSTRICT) either).
But perhaps you can see any flaws in this refined solution as well?