Page 2 of 2
Posted: Wed Apr 25, 2007 1:53 pm
by Alboin
Solar wrote:Two, before you make claims like "C++ done right", imagine that there might be people out there who have a different idea of what is "broken" in C++. I, for one, feel quite OK in a language that doesn't do GC.
GC? Garbage...Can? Giant Cat!? Yes, that's it.
Seriously, though, in a language like C, C++, etc. if you allocate something you
should free it. How hard is that? To me, GC's are somewhat of a clutter. I guess I just enjoy the simplicity of C...
If you want something different than C, then try a different language paradigm. Calling D an alternative language doesn't make any sense. It is imperative: the same as C. If you know one imperative language, then you can very easily program in any other imperative language.
Posted: Wed Apr 25, 2007 3:25 pm
by Colonel Kernel
Alboin wrote:Seriously, though, in a language like C, C++, etc. if you allocate something you should free it. How hard is that?
As someone who has worked on commercial software projects of non-trivial size for nearly a decade, I laugh at your naïveté.
In all seriousness though, it is really a question of scale and environment. For OS dev, manual memory management is tractable, as long as you test for leaks very thoroughly...
Posted: Wed Apr 25, 2007 4:10 pm
by Kevin McGuire
I never thought about it like that, but a company is looking to make money - and whatever language aids in less bugs and meets the target goal is going to be used.
But, I think that there are some advantages to GC performance wise in at least select cases. I do not know if there are any practical applications of this.
Posted: Wed Apr 25, 2007 4:25 pm
by mystran
Colonel Kernel wrote:Alboin wrote:Seriously, though, in a language like C, C++, etc. if you allocate something you should free it. How hard is that?
As someone who has worked on commercial software projects of non-trivial size for nearly a decade, I laugh at your naïveté.
In all seriousness, properly followed RAII and correct use of auto_prt will make that goal quite a bit more tractable, so it's a lot easier in C++ than almost any other language.
It's not like programs written in languages like Java never leaked any memory, as their garbage collectors can't tell semantic garbage from live data, so you still end up doing some amount of manual memory management. And where as C++ style RAII trivially generalizes to any resource whatsoever, garbage collectors are only good for collecting memory, and rest of your resources you must manually manage anyway.
In fact, I've had less trouble with deterministic resource management using RAII than I've had with people expecting garbage collectors to clean after them. In fact, the number one thing I miss whether I'm programming in C or Java is deterministic destructors. Especially once you throw exceptions into the mix (like in Java), it becomes almost impossible to track anything reliably.
And yes, I know, D supposedly does support RAII, which is a good thing.
Posted: Wed Apr 25, 2007 5:07 pm
by Colonel Kernel
Kevin McGuire wrote:But, I think that there are some advantages to GC performance wise in at least select cases. I do not know if there are any practical applications of this.
It's not so much practical applications of fast GC as it is identifying the circumstances in which GC is faster than manual memory management. A typical stop & copy generational collector like the one used by the CLR can allocate memory very quickly, and there is very little space overhead for tracking each object. For code that allocates many small objects frequently, this is more efficient than typical "unmanaged" heap allocation. Deallocation can take about as long as handling a page fault, which is not good for real-time applications, but otherwise the cost is negligible and is amortized over the many (and much faster) allocations.
mystran wrote:In all seriousness, properly followed RAII and correct use of auto_prt will make that goal quite a bit more tractable, so it's a lot easier in C++ than almost any other language.
Oh, I agree. RAII is great, and IMO all languages should have it -- at least for non-memory resources, if not for memory management.
There are at least two problems with manual memory management though, even with RAII -- dealing with cyclical data structures, and implementing non-trivial
lock-free algorithms -- hazard pointers are not easy to understand IMO.
I'll give you an example of a problem with the first case that I'm having right now. I'm working on a component that internally keeps track of many things using a highly-connected object graph (I'm afraid I can't be very specific here). In particular, many objects in this graph have parent-child logical relationships and bi-directional links between them. The problem is, any thread can try to insert and remove nodes from this graph at any time in such a way that the insertion or removal of an entire group of nodes at once must be atomic. Trying to manage the lifetime of the graph nodes in a thread-safe manner during operations that might affect many nodes at once is very non-trivial! Especially when the links are necessarily non-symmetric -- some will be shared_ptrs, and some will have to be weak_ptrs. GC would at least remove one concern from this particular Gordian knot.
Posted: Wed Apr 25, 2007 5:55 pm
by Kevin McGuire
I'll give you an example of a problem with the first case that I'm having right now. I'm working on a component that internally keeps track of many things using a highly-connected object graph (I'm afraid I can't be very specific here). In particular, many objects in this graph have parent-child logical relationships and bi-directional links between them. The problem is, any thread can try to insert and remove nodes from this graph at any time in such a way that the insertion or removal of an entire group of nodes at once must be atomic. Trying to manage the lifetime of the graph nodes in a thread-safe manner during operations that might affect many nodes at once is very non-trivial! Especially when the links are necessarily non-symmetric -- some will be shared_ptrs, and some will have to be weak_ptrs. GC would at least remove one concern from this particular Gordian knot.
Oh. Like a virtual file system. Where the certain branches become locked with a thread inside of it. So you do not want to actually delete that branch by the action of another thread but instead allow GC to do that when no thread is there any longer to keep from breaking the link and crashing?
Or a binary tree with no locks.. have no really thought that one through. hehe.
Posted: Wed Apr 25, 2007 6:13 pm
by mystran
Colonel Kernel wrote:Trying to manage the lifetime of the graph nodes in a thread-safe manner during operations that might affect many nodes at once is very non-trivial! Especially when the links are necessarily non-symmetric -- some will be shared_ptrs, and some will have to be weak_ptrs. GC would at least remove one concern from this particular Gordian knot.
Now after bashing GC, can I ask whether there's some reason you don't just use a garbage collector?
Posted: Wed Apr 25, 2007 11:23 pm
by Colonel Kernel
mystran wrote:Now after bashing GC, can I ask whether there's some reason you don't just use a garbage collector?
I would if I could, but the component has to be implemented in C and/or C++ (it implements a standard C API that has existed for over 15 years) and it has to be portable to 7 different *nixes. Remember, I work on commercial software -- I don't get to choose what technology to use.
Posted: Thu Apr 26, 2007 12:51 am
by mystran
Colonel Kernel wrote:
I would if I could, but the component has to be implemented in C and/or C++ (it implements a standard C API that has existed for over 15 years) and it has to be portable to 7 different *nixes. Remember, I work on commercial software -- I don't get to choose what technology to use.
C and/or C++ whether portable or not, actually doesn't rule out GC. There's Boehm GC which works with both of the previous languages, and pretty much any *nix by now.. but then again...
What I was actually thinking of, is that if you have a largish, potentially cyclic graph, which needs to be concurrently modified, then you're probably involving several threads. Now, especially if the graph nodes are C++ objects, one could do a special case Dijkstra tricolor on them quite easily, if one extra thread for the collector doesn't hurt. The point is, if it's all data and one doesn't need to deal with finalizers or stuff like that, one avoids most of the pitfalls of a garbage collector.
But well, ok.. I admit that if you've never researched GCs it's probably a bit hazard to go trying to write one... especially for a commercial program
Posted: Thu Apr 26, 2007 8:54 am
by Colonel Kernel
mystran wrote:C and/or C++ whether portable or not, actually doesn't rule out GC. There's Boehm GC which works with both of the previous languages, and pretty much any *nix by now.. but then again...
Heh... I doubt the customer would approve that.
One of the *nix variants is very, very old and poorly maintained.
But well, ok.. I admit that if you've never researched GCs it's probably a bit hazard to go trying to write one... especially for a commercial program
I'm sure I would find it very interesting, but my boss would strangle me if I tried.