Conversation started Dec 7, 2016 at 17:50.
jrh
jrh
Dec 7, 2016 17:50
@amon I guess in that case the class with the method that called the constructor of the unmanaged resource would be the only one responsible for freeing it? The other ones would just be taking the resource "by reference". I prefer to keep unamanged resources as local variables within a single function (so I can use using) but it just doesn't work all the time, e.g., if I have to display an image.
Looking back that was what I did in the code, I didn't really follow that deliberately but that's just sort of where the resources fell into place.
If there's no chance of misunderstanding (i.e., it's generally accepted that an image would be returned by reference) then that makes my life easier, I can give access to the Image to display it but I don't have to worry about client code disposing the image being displayed because they would understand that it might be used in other places.
Dec 7, 2016 18:12
@jrh Yes. Some languages are a bit more helpful and have an explicit concept of “owning” and “borrowing” a reference.
However, a method that creates a resource needing cleanup may also transfer that responsibility, for example a factory won't also do cleanup. Ideally that's obvious from context and clearly documented, but then again there is this thing called the real world…
It would be extremely confusing if accessing an object through a property would transfer ownership, but if it's a method called CreateFoo(), transferring ownership seems sensible.
You're not changing the human. He can still go on vacation. Like I said, give supervisors the ability to unlock files and assign them to someone else. If you look at the answers posted so far, I am now the third person who has recommended this. — Robert Harvey 5 mins ago
[sigh] -- The only thing worse than asking misguided questions is not taking the advice of the people you're asking. It suggests that all you want is to have your preconceived answer validated by others.
jrh
jrh
@amon makes sense, thanks. The idea of owning and borrowing a reference having language support is very interesting, what languages support this? (Also: for some reason in the back of my mind I assumed the idea of "Ownership" was not as important in C# as it was in C or C++, due to the GC I guess)
That wasn't a correct assumption, obviously. It only made things more confusing.
@jrh C++ pioneered this to a degree. If you have an object by value, you own it (duh). A reference is always borrowed. A pointer has no inherent ownership semantics. But there are various smart pointers like unique_ptr (single owner), shared_ptr (refcounted, multiple owners). Rust elaborated on that system and made ownership/lifetimes part of the type system. References can be qualified with lifetimes; the type checker prevents you from holding a reference longer than it exists.
Escape analysis is also used by some garbage-collected language implementations to avoid GC overhead for local variables – if only I use that object, I can allocate it on the stack.
Because C++ has RAII (deterministic destruction allows us to couple resource management with object lifetime) resource management is straightforward. GC only automated management of memory resources. Java's Autoclosable+try-with-resource, C#'s IDisposable+using statement, Python's context managers+with statement all add resource management back to the language, but it's not as safe as RAII: now the using programmer has to write extra code to ensure correctness, and the compiler can't help.
Dec 7, 2016 18:29
RAII is safer than garbage collection? Surely not.
jrh
jrh
@amon interesting analysis, I think I got a little confused about ownership when I no longer had to differentiate between pointers to things and the things themselves for reference types in C#.
IDisposable ought to be just as safe as RAII. It even takes exceptions into account, IIRC.
jrh
jrh
using does take exceptions into account.
using is just syntactic sugar around a try catch block.
(get my keywords mixed up sometimes)
jrh
jrh
(I get stuck in VB land sometimes, I go back and forth between C#, C and VB.NET and you can tell which one I'm Using When I Capitalize Every Single Thing)
Dec 7, 2016 18:33
@RobertHarvey for general resource management? RAII is safer. If I write a class that needs to do stuff in the destructor, I can be sure the destructor will be invoked at a specific time (for local variables: when the current scope is left, for instance variables: after the enclosing instances destructor has run). GC may only happen much later. The only way to mess that up is to create an object with the new operator, which in C++ screams “I know what I'm doing!”.
In C# or Java, it's easy to mess up an IDisposable/AutoClosable object: I just create it and forget to put it into an using/try-with-resource statement.
 
Conversation ended Dec 7, 2016 at 18:34.