Thread overview
A handle is a magic value pointer
May 31, 2004
Vathix
May 31, 2004
Mike Swieton
May 31, 2004
Ilya Minkov
May 31, 2004
Derek Parnell
Jun 01, 2004
Ilya Minkov
Jun 02, 2004
Derek Parnell
May 31, 2004
Andy Friesen
Jun 01, 2004
Walter
May 31, 2004
In garbage.html it says,
"Do not store magic values into pointers, other than null."
HWND and its friends are magic value pointers. Perhaps something like this
should go in object.d for all handle types:

struct handle
{
   int get() { return value; }
   int set(int value) { this.value = value; }
   private int value;
}

The struct is passed by value and the get/set members are just for handle implementors (or curious users).


May 31, 2004
On Mon, 31 May 2004 08:17:37 -0400, Vathix wrote:

> In garbage.html it says,
> "Do not store magic values into pointers, other than null."
> HWND and its friends are magic value pointers. Perhaps something like this
> should go in object.d for all handle types:
> 
> struct handle
> {
>    int get() { return value; }
>    int set(int value) { this.value = value; }
>    private int value;
> }
> 
> The struct is passed by value and the get/set members are just for handle implementors (or curious users).

If an int is a valid way of storing a handle, why not just use an int? In any case, I don't see how this would solve the problem: there's still a 'magic value', it's just a bit more hidden now (and the GC will still see it).

Mike Swieton
__
The present is theirs; the future, for which I really worked, is mine.
	- Nikola Tesla

May 31, 2004
Mike Swieton schrieb:

> If an int is a valid way of storing a handle, why not just use an int?

I think this is good, since HANDLEs are not pointers, i.e. you don't get a valid memory location when you dereference them. At least as far as i know. Any counter-examples?

Even then, one could take a pointer-sized int, since this memory would be OS-allocated and thus not of interest to the GC.

> In any
> case, I don't see how this would solve the problem: there's still a 'magic
> value', it's just a bit more hidden now (and the GC will still see it).

Some GCs are allowed to be dumber or smarter than the usual mark&sweep. This is aimed at optimization of smart GCs which would (1) be (at least sometimes) able to distinguish a pointer from a non-pointer by type information, and (2) if the type identification says it's definately a pointer, don't bother checking whether a pointer actually points at an existing memory location.

-eye
May 31, 2004
Vathix wrote:

> In garbage.html it says,
> "Do not store magic values into pointers, other than null."
> HWND and its friends are magic value pointers. Perhaps something like this
> should go in object.d for all handle types:
> 
> struct handle
> {
>    int get() { return value; }
>    int set(int value) { this.value = value; }
>    private int value;
> }
> 
> The struct is passed by value and the get/set members are just for handle
> implementors (or curious users).

I think the intent here is that a pointer into garbage collected memory ought to look like a pointer into garbage collected memory, and not an integer.  Handles from external APIs (like win32) are obviously not important to the GC.

 -- andy
May 31, 2004
On Mon, 31 May 2004 21:31:42 +0200, Ilya Minkov wrote:

> Mike Swieton schrieb:
> 
>> If an int is a valid way of storing a handle, why not just use an int?
> 
> I think this is good, since HANDLEs are not pointers, i.e. you don't get a valid memory location when you dereference them. At least as far as i know. Any counter-examples?

I seem to remember that the early Macintosh operating system defined a handle as a (**void). In other words, a handle was the address of an address of something. This allowed the something's to be moved around so long as the application always used the handle to find's its current address. This was a co-operative multi-tasking system, so when control was yielded to the OS, it would sometimes do a garbage collection/compaction and move structures around in a non-predictive manner.

> Even then, one could take a pointer-sized int, since this memory would be OS-allocated and thus not of interest to the GC.

Yeah, that should work too.


-- 
Derek
1/Jun/04 9:13:38 AM
June 01, 2004
Derek Parnell schrieb:

> I seem to remember that the early Macintosh operating system defined a
> handle as a (**void). In other words, a handle was the address of an
> address of something. This allowed the something's to be moved around so
> long as the application always used the handle to find's its current
> address. This was a co-operative multi-tasking system, so when control was
> yielded to the OS, it would sometimes do a garbage collection/compaction
> and move structures around in a non-predictive manner.

We're talking of the translation of the Windows API headers now. If some (e.g. embedded) operating system uses some actual type - fine. If i recall correctly Windows HANDLEs are not dereferenced by the user, and only passed as parameter to various functions. Recall that in all modern operting systems, processes and operating system have completely separated adress spaces. Thus, even if a handle is a pointer to the OS adress space, it is of no meaning to the application, because the only way to use it is to pass it back to the OS functions. Otherwise, HANDLEs are often just constants or enumeration values. I would be very surprised to see a Windows API return a pointer into application's adress space as a HANDLE and not as a plain old pointer.

-eye
June 01, 2004
"Vathix" <vathixSpamFix@dprogramming.com> wrote in message news:c9f7nt$6eb$1@digitaldaemon.com...
> In garbage.html it says,
> "Do not store magic values into pointers, other than null."
> HWND and its friends are magic value pointers. Perhaps something like this
> should go in object.d for all handle types:

In general, such magic values are bad ideas. In practice, it is only a bad idea with D's gc if the magic value actually is an address pointing inside the gc heap. This does not happen with Windows' choice of HWND magic values.

An example of a very bad magic value idea is to store some flags in the bottom two bits of a pointer, on the rationale that pointers are aligned to 4 byte boundaries. Another bad idea is to use magic values like 0xDEADBEEF. Values that are less than 0xFFFF or are -1 tend to be ok, though I still strongly discourage their use unless forced to, like the Win32 API.


June 02, 2004
On Tue, 01 Jun 2004 17:09:30 +0200, Ilya Minkov wrote:

> Derek Parnell schrieb:
> 
>> I seem to remember that the early Macintosh operating system defined a handle as a (**void). In other words, a handle was the address of an address of something. This allowed the something's to be moved around so long as the application always used the handle to find's its current address. This was a co-operative multi-tasking system, so when control was yielded to the OS, it would sometimes do a garbage collection/compaction and move structures around in a non-predictive manner.
> 
> We're talking of the translation of the Windows API headers now. If some (e.g. embedded) operating system uses some actual type - fine. If i recall correctly Windows HANDLEs are not dereferenced by the user, and only passed as parameter to various functions. Recall that in all modern operting systems, processes and operating system have completely separated adress spaces. Thus, even if a handle is a pointer to the OS adress space, it is of no meaning to the application, because the only way to use it is to pass it back to the OS functions. Otherwise, HANDLEs are often just constants or enumeration values. I would be very surprised to see a Windows API return a pointer into application's adress space as a HANDLE and not as a plain old pointer.
> 
> -eye

I was just giving an example of where the term 'handle' as been used as a 'pointer to a pointer'. Even in the Windows API I believe there are a few of these examples...

 The PRINTDLG structure contains four such 'handles' :
	hDevMode
	hDevNames
	hPrintTemplate
	hSetupTemplate

-- 
Derek
2/Jun/04 10:00:31 AM