www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why same pointer type for GC and manual memory?

reply IGotD- <nise nise.com> writes:
I'm trying to find the rationale why GC pointers (should be names 
managed pointers) are using the exact same type as any other 
pointer.

Doesn't this limit the ability to change the default GC type?
Doesn't this confusion make GC pointers just as unsafe as raw 
pointers?
Has there been any prior discussion about introducing managed 
pointers in D?
Nov 13 2019
next sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 13 November 2019 at 11:07:12 UTC, IGotD- wrote:
 I'm trying to find the rationale why GC pointers (should be 
 names managed pointers) are using the exact same type as any 
 other pointer.
I assume you mean a GC that scans (not ref counting). GC pointers only need to be protected from being released, so regular "borrowing" pointers would be ok. That ought to be the most common pointer type in function signatures. But then you would need a concept of "raw" pointers and "owning" pointers in addition.
 Doesn't this confusion make GC pointers just as unsafe as raw 
 pointers?
Only if it can be freed or if you can construct a pointer from integers so that pointers can be hidden when GC scans memory. Which is a reason for why high level GC languages treat pointers/references in an abstract way (no address information available).
 Has there been any prior discussion about introducing managed 
 pointers in D?
Yes, there has been several discussions in the forums over the years. One argument against would be that people would not be able to use libraries that used a specific pointer type. That could be solved by using templated pointers or using borrowed-pointer-types in interfaces. Another argument against has been that it would create a combinatorial explosion when people try to mix different pointer types. It might lead to more object code bloat, but should not be deal breaking.
Nov 13 2019
prev sibling next sibling parent reply Dukc <ajieskola gmail.com> writes:
On Wednesday, 13 November 2019 at 11:07:12 UTC, IGotD- wrote:
 I'm trying to find the rationale why GC pointers (should be 
 names managed pointers) are using the exact same type as any 
 other pointer.

 Doesn't this limit the ability to change the default GC type?
What does grabage collector type mean?
 Doesn't this confusion make GC pointers just as unsafe as raw 
 pointers?
It does if you pass the pointers to somewhere the garbage collector does not know about. However, normally it has a list of all memory used by the program -even the memory that is not managed by it. But if you, for example, put a pointer to memory allocated by some C program that is totally unaware of the GC, you need to either manually register (and unregister) the memory to the GC, or keep a copy of the pointer in somewhere the GC knows about. Assuming the pointed memory is controlled by GC, that is. Otherwise, the GC will not find the pointer during collection and think you have stopped using the memory it points to.
 Has there been any prior discussion about introducing managed 
 pointers in D?
I'm not 100% sure what managed pointers mean -Are they so that you can't pass them to unregistered memory? A library solution would likely do -wrap the pointer in a struct and make it system to extract it's pointer as "raw". So you cannot put it to C-allocated arrays without type casting, which you probably don't do accidently.
Nov 13 2019
parent reply IGotD- <nise nise.com> writes:
On Wednesday, 13 November 2019 at 15:30:33 UTC, Dukc wrote:
 I'm not 100% sure what managed pointers mean -Are they so that 
 you can't pass them to unregistered memory? A library solution 
 would likely do -wrap the pointer in a struct and make it 
  system to extract it's pointer as "raw". So you cannot put it 
 to C-allocated arrays without type casting, which you probably 
 don't do accidently.
Best example is probably managed C++, an MS extension to C++ which is now deprecated. However, it server as an interesting example where MS extended C++ with a ^gc type. https://en.wikipedia.org/wiki/Managed_Extensions_for_C%2B%2B The ^gc type can actually be anything, raw pointer, reference counted or any fat pointer of choice. The benefit with this is that it doesn't intrude on C++ classical raw pointers, they are kept the same without any restrictions. GC algorithm is easily swappable like with Nim. The D class is sort of a fat pointer but it only applies for classes, it would be nice to extend this to any memory as well (Yes you can GC allocate anything but then you get a raw pointer without the type distinction that it is a GC allocated object).
Nov 13 2019
next sibling parent reply Suleyman <sahmi.soulaimane gmail.com> writes:
On Wednesday, 13 November 2019 at 16:43:27 UTC, IGotD- wrote:
 Best example is probably managed C++, an MS extension to C++ 
 which is now deprecated.
MS Managed C++ was superseded by C++/CLI[1] which was standardized. They actually retained the special syntax for GC pointers. One of the motivations if I understand correctly is to let the programmers easily distinguish which pointers should be freed and which ones are managed by the GC. It's not a bad idea when there is extensive use of both manual memory management and garbage collection. [1] https://en.wikipedia.org/wiki/C%2B%2B/CLI
Nov 13 2019
parent kinke <noone nowhere.com> writes:
On Thursday, 14 November 2019 at 01:08:58 UTC, Suleyman wrote:
 On Wednesday, 13 November 2019 at 16:43:27 UTC, IGotD- wrote:
 Best example is probably managed C++, an MS extension to C++ 
 which is now deprecated.
MS Managed C++ was superseded by C++/CLI[1] which was standardized. They actually retained the special syntax for GC pointers. One of the motivations if I understand correctly is to let the programmers easily distinguish which pointers should be freed and which ones are managed by the GC. It's not a bad idea when there is extensive use of both manual memory management and garbage collection.
IIRC (it's been a while), a mandatory reason for that distinction is that the .NET GC may move managed objects in memory (compaction) and so you have to pin them first to get a stable pointer.
Nov 14 2019
prev sibling parent Kagamin <spam here.lot> writes:
On Wednesday, 13 November 2019 at 16:43:27 UTC, IGotD- wrote:
 On Wednesday, 13 November 2019 at 15:30:33 UTC, Dukc wrote:
 I'm not 100% sure what managed pointers mean -Are they so that 
 you can't pass them to unregistered memory? A library solution 
 would likely do -wrap the pointer in a struct and make it 
  system to extract it's pointer as "raw". So you cannot put it 
 to C-allocated arrays without type casting, which you probably 
 don't do accidently.
Best example is probably managed C++, an MS extension to C++ which is now deprecated. However, it server as an interesting example where MS extended C++ with a ^gc type.
AFAIK those managed pointers are not general purpose, but specifically for managed .net objects, you can't allocate unmanaged object on managed heap, and managed object on unmanaged heap. In case of D you would have raw pointers for unmanaged objects allocated in C heap and D GC heap, and additional .net pointers for .net objects.
Nov 14 2019
prev sibling parent reply user1234 <user.1234 4321.user> writes:
On Wednesday, 13 November 2019 at 11:07:12 UTC, IGotD- wrote:
 I'm trying to find the rationale why GC pointers (should be 
 names managed pointers) are using the exact same type as any 
 other pointer.

 Doesn't this limit the ability to change the default GC type?
 Doesn't this confusion make GC pointers just as unsafe as raw 
 pointers?
 Has there been any prior discussion about introducing managed 
 pointers in D?
One other reason is that special pointers are not good for debugging and have a runtime cost... in D it's not like in a VM.
Nov 15 2019
parent reply IGotD- <nise nise.com> writes:
On Friday, 15 November 2019 at 08:58:43 UTC, user1234 wrote:
 On Wednesday, 13 November 2019 at 11:07:12 UTC, IGotD- wrote:
 I'm trying to find the rationale why GC pointers (should be 
 names managed pointers) are using the exact same type as any 
 other pointer.

 Doesn't this limit the ability to change the default GC type?
 Doesn't this confusion make GC pointers just as unsafe as raw 
 pointers?
 Has there been any prior discussion about introducing managed 
 pointers in D?
One other reason is that special pointers are not good for debugging and have a runtime cost... in D it's not like in a VM.
It's true it has a runtime cost but I'm wondering if it isn't worth it. There will be an extra dereference of course but this is only done once per for every piece that use the fat pointer. With a fat pointer you could also provide more information, allocated size for example which makes it possible to safely cast the pointer to anything checking that the boundaries are correct. Also reading a fat pointer (like *ptr) can check the bounds. Size information is also handy for some allocators, buddy allocator for example where storing the size in the allocated block is something that you not always want to as it throws the memory off the natural alignment which is one of the benefits of the buddy allocator. In the fat pointer you could store more information like reference count, type of allocator, a pointer to free function (makes it possible to hotswap allocators). When it comes to debugging, then you need to parse the fat pointer, just like it parses common containers classes. This is not a too big deal I think.
Nov 15 2019
parent reply Basile B. <b2.temp gmx.com> writes:
On Friday, 15 November 2019 at 10:55:55 UTC, IGotD- wrote:
 On Friday, 15 November 2019 at 08:58:43 UTC, user1234 wrote:
 On Wednesday, 13 November 2019 at 11:07:12 UTC, IGotD- wrote:
 I'm trying to find the rationale why GC pointers (should be 
 names managed pointers) are using the exact same type as any 
 other pointer.

 Doesn't this limit the ability to change the default GC type?
 Doesn't this confusion make GC pointers just as unsafe as raw 
 pointers?
 Has there been any prior discussion about introducing managed 
 pointers in D?
One other reason is that special pointers are not good for debugging and have a runtime cost... in D it's not like in a VM.
It's true it has a runtime cost but I'm wondering if it isn't worth it. There will be an extra dereference of course but this is only done once per for every piece that use the fat pointer. With a fat pointer you could also provide more information, allocated size for example which makes it possible to safely cast the pointer to anything checking that the boundaries are correct. Also reading a fat pointer (like *ptr) can check the bounds. Size information is also handy for some allocators, buddy allocator for example where storing the size in the allocated block is something that you not always want to as it throws the memory off the natural alignment which is one of the benefits of the buddy allocator. In the fat pointer you could store more information like reference count, type of allocator, a pointer to free function (makes it possible to hotswap allocators). When it comes to debugging, then you need to parse the fat pointer, just like it parses common containers classes. This is not a too big deal I think.
TBH I see your point but D is a system programming language. Even if there's a GC you can also do Manual Memory Mangement (sometimes you'll see "MMM "to refer to that in the forums), RC, and you can also write custom machine code in asm blocks. In most of the case, if you just stick to the GC way, it'll be alright, even if pointers are actual machine pointers, i.e usable in asm blocks ;) Recently some guys have discovered however that an aggressive anti virus scanner could cause problems... Anyway, just to say, D produces machine code and doesn't requires a VM... if you need fat pointers for a custom memory management, free to you. I don't think this will ever change.
Nov 15 2019
parent IGotD- <nise nise.com> writes:
On Friday, 15 November 2019 at 11:32:07 UTC, Basile B. wrote:
 TBH I see your point but D is a system programming language. 
 Even if there's a GC you can also do Manual Memory Mangement 
 (sometimes you'll see "MMM "to refer to that in the forums), 
 RC, and you can also write custom machine code in asm blocks.

 In most of the case, if you just stick to the GC way, it'll be 
 alright, even if pointers are actual machine pointers, i.e 
 usable in asm blocks ;)

 Recently some guys have discovered however that an aggressive 
 anti virus scanner could cause problems...

 Anyway, just to say, D produces machine code and doesn't 
 requires a VM... if you need fat pointers for a custom memory 
 management, free to you.

 I don't think this will ever change.
Nim which is a systems programming language handles the GC part nicely. With Nim you can plug and play many different types of GC types. https://nim-lang.org/docs/gc.html --gc:refc Deferred reference counting with cycle detection, thread local heap, default. --gc:markAndSweep Mark-And-Sweep based garbage collector, thread local heap. --gc:boehm Boehm based garbage collector, stop-the-world, shared heap. --gc:go Go lang like garbage collector, stop-the-world, shared heap. --gc:regions Stack based garbage collector. --gc:none No garbage collector. so the architecture of Nim allows this just by a compiler switch. Would D even support reference counting as Nim defaults to with the current mixup of raw and GC pointers?
Nov 19 2019