Hacker News new | past | comments | ask | show | jobs | submit login

Please get rid of GC :(

I want to have smart pointers instead




No problem, just add the @nogc annotation to your main function.

    int main(string[] args) @nogc { ... }


I haven't used D much- how much of an impact does that have when using the standard library or other libraries? Is there a good way to use things that assume a GC even when it's disabled?


There are many parts of the std lib that assume GC usage. When you mark a function as @nogc, DMD does a compile-time check and will not compile your program if there's a GC call. Applying this to main means that your entire program will by necessity be GC free.


Right, I understand that it effectively eliminates GC usage, I'm just wondering how much of an impact that has on what tools you have. In the extreme, I can imagine it degenerating into basically writing C, for example.


You have access to all of std.range and std.algorithm, most of std.datetime, many functions in std.string and std.digest, and others scattered throughout the std lib. The main thing you'll want to look at is std.experimental.allocator, which has tons of tools for manual memory allocation.

Most of the community packages out there use the GC. Some though are transitioning to a std.experimental.allocator interface, like this containers library https://github.com/economicmodeling/containers


See Sociomantic 's Ocean library. But you don't need to go that far in practice in most uses. If you keep GC heap small, disable the GC in critical code paths, have threads that the GC doesn't get involved in, and use allocators most people will be fine.


Actually, please don't get rid of the GC. The GC makes programming easier and there is rust now if a programmer believes that they can not possibly tolerate one. Complaining about the GC is like complaining about python's white space, lisp's parentheses, go's lack of generics etc. It's demanding that the entire language changes to suit the complainant. However, if you're going to have one and people keep bringing it up, you should work hard to make sure that it is the best that it can be. Golang has been very good in this regard with their very publicized work on reducing the stop the world time of their GC. Personally, I think that it would be a win if Dlang did something similar (in addition to the @nogc stuff). It doesn't need to concentrate on reducing the GC pause time, it just needs to be seen to be getting better.


Isn't it possible to have GC as an library rather than a language construct?

The way I see it, GC should just belong as deferred_ptr


Smart pointers are a form of garbage collection. (I'm assuming you mean reference counting).


Not all smart pointers are reference counted.


Sure, smart pointers can also refer to bounds checking, etc.

In this case, grandparent did mention a memory management technique, namely garbage collection.

Memory management + plus typically required thread safety usually means reference counting.


uniq_ptr<T> in C++ and Box<T> in Rust are both considered smart pointers, dealing with memory management, and don't do any reference counting, bounds checking, or anything else like that at runtime. They're a compile-time abstraction only.


This is not really accurate. A unique_ptr<T> move assignment must check the target location to see if it's null, and if not, free the underlying object. It also has to clear the source location. This is more than just a compile-time abstraction compared to raw pointers, even if modern compilers can elide the code most of the time.

Also, the lack of checking leads to unique_ptr<T> dereferences potentially having undefined behavior (i.e. whenever you try to dereference a unique pointer that is null [1]).

[1] http://en.cppreference.com/w/cpp/memory/unique_ptr/operator*


I think you're picking nits. The equivalent raw pointer code would also have to free a pointer it was overwriting, so I'm not sure that's so interesting (definitely not in terms of "zero cost abstractions").

That said, the null checks required for C++'s destructor semantics are definitely a little more interesting in this respect, given one is rarely going to do this with raw pointers (although the cases when you don't need to do it also seem like cases the optimiser can handle fairly easily), but an extra branch and/or write at least seems significantly qualitatively different to the full reference counting that people often think of when talking about "smart pointers", which is the point the parent is trying to make (smart pointers aren't just reference counting).


I'm not picking nits. This is not just about the freeing (which I assume will happen in the minority of cases), but also the test-and-branch code generated (plus the zeroing of the source location), which is something that you can't just ignore even if branch prediction is perfect. The claim that they are a "compile-time abstraction only" is pretty absolute.

Also, the cost of it not being memory-safe should not be ignored.


I was claiming you were picking nits because the main point of the comment is that smart pointer != reference counting, the incorrect "only" claim is somewhat orthogonal. And, my point about the qualitative difference between the runtime behaviour is definitely true (although I'll now strength it to a quantitative one: moving a unique_ptr doesn't require dereferencing it, unlike a reference counted one, and nor does it require any synchronisation, unlike thread-safe reference counting ala shared_ptr).

In any case, it is unfortunate that unique_ptr is not memory safe, but it also not at all notable, as pretty much nothing in C++ is completely memory safe (even the other smart pointers like shared_ptr).


This is why I wrote "this is not really accurate" as opposed to "this is wrong". The claim was considerably broader than "smart pointer != reference counting".

The deeper problem is that unique pointers essentially are a sort of linear/affine type system, but that C++ leaves the actual checks to the runtime (which implements some, but not all of them).


Ah! That makes perfect sense, thank you. I guess it's just Box<T>, then :p (This is the difference in move semantics between C++ and Rust showing.)

I think my original point still stands here though: smart pointers != refcounting, inherently.


Good point.

Somehow I wasn't considering unique_ptr<T> as a smart pointer, despite using it all the time for resource management to avoid writing wrapper classes.

I do now, you're right.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: