www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - A handle is a magic value pointer

reply "Vathix" <vathixSpamFix dprogramming.com> writes:
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
next sibling parent reply Mike Swieton <mike swieton.net> writes:
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
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
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
parent reply Derek Parnell <derek psych.ward> writes:
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
May 31 2004
parent reply Ilya Minkov <minkov cs.tum.edu> writes:
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
Jun 01 2004
parent Derek Parnell <derek psych.ward> writes:
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
Jun 01 2004
prev sibling next sibling parent Andy Friesen <andy ikagames.com> writes:
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
prev sibling parent "Walter" <newshound digitalmars.com> writes:
"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.
Jun 01 2004