On Jan 31, 2013, at 11:07 PM, "monarch_dodra" <monarchdo...@gmail.com> wrote:
> On Thursday, 31 January 2013 at 23:53:26 UTC, Steven Schveighoffer wrote: >> >> A destructor should ONLY be used to free up resources other than GC >> allocated memory. Because of that, it's generally not used. >> >> It should be used almost as a "last resort". >> >> For example, a class that holds a file descriptor should have both a >> destructor (which closes the descriptor) and a manual close method. The >> former is to clean up the file descriptor in case nobody thought to close it >> manually before all references were gone, and the latter is because file >> descriptors are not really managed by the GC, and so should be cleaned up >> when they are no longer used. >> >> This kind of gives us a paradox, since the class is managed via the GC, how >> do you know it's no longer used (that is, how do you know this is the last >> reference to it)? That is really up to the application design. But I >> wouldn't recommend relying on the GC to clean up your descriptors. >> >> -Steve > > I've actually run into this very issue: I was iterating on files, opening > them, and placing the descriptor in GC-allocated RAII data. I can't remember > if class or struct, but not a big issue. Come to think about it, I think I > was using "File", but allocating them because I thought they were classes > `auto f = new File("my file", "r")`. > > After running for a second, my program halts, because an exception was thrown > trying to open a new file: > "Cannot open file: Too many open file handles". > > It was basically: Sure, the GC will destroy and close files for you... if you > forget... eventually... > > I ended up closing them in scope(exit) blocks. Problem immediately solved. Or > I could have stopped allocating my File's on the heap. > > Either way, it shows you shouldn't rely on the GC for deterministic > destruction. The GC currently doesn't finalize structs, only classes. So that's an issue as well.