3 ms·
As I said and covered, value types are not deterministic resource management. Those are orthogonal concepts. And in fact, confusing the two can lead to proble
by cogman10 3y ago
As I said and covered, value types are not deterministic resource management. Those are orthogonal concepts.
And in fact, confusing the two can lead to problems. C#, for example, does not necessarily store value types on the stack. [1] Those can be allocated on the heap. C# doesn't even give a guarantee of how long a value type will live. It's only guarantee is the one I outlined earlier, that this thing is represented as a block of memory rather than a pointer and that when you pass this around it's done as a copy.
If your assumption is that "this thing is freed up immediately when it's unused" that's a faulty assumption. Being a value type imparts no guarantee on how long something will live.
This is more than just a philosophical definition.
If you want deterministic resource management in C#, you use the `using` statement. If you are in java, it's `try-with-resources`. If you are in C++, you rely on RAII. If you are in C... good luck. None of those things have anything to do with value types. Because lifetime and type aren't related in those languages
> Once you abandon entirely the crazy idea that the type of a value has anything whatsoever to do with the storage, it becomes much easier to reason about it.
[1] https://ericlippert.com/2010/09/30/the-truth-about-value-types/ https://ericlippert.com/2010/09/30/the-truth-about-value-typ...
- neonsunset 3y agoThis is an ancient article. Pretty much only Rust has .drop() with such strong steroids. Either way struct in C# means something very specific and it is the same as struct in C. You can cast a malloced pointer in C to a struct and use it as such, you can do the same in C# (not that you should, but you can). In terms for article contents - structs absolutely do go on the stack when you declare them as locals except select scenarios: async and iterator methods, both of which can capture variables that live across yields or awaits into a state machine struct or class (debug/release difference, and also ValueTask which does not alloc when it completes synchronously). If you care about memory lifetimes, the compiler will helpfully error out when you are returning a 'ref' to a local scope, violating the lifetime (because it has rudimentary lifetime analysis underneath hence scoped and unscoped semantics).
- steveklabnik 3y ago> This is an ancient article. It was posted yesterday, 4 March 2024.
- neonsunset 3y agoI meant the Eric Lippert one :) It talks about that spec does not say where structs go. And yet, all existing implementations today have more or less identical behavior (and by all I mean .NET (CoreCLR), Mono (the dotnet/runtime flavour), Mono (the Unity flavour) and .NET Framework. With that said, only respect to the article's content and, of course, Eric Lippert. For the context of the discussion, however, it may be misleading. C# has gained quite a few low level primitives since it has been written too.
- steveklabnik 3y agoAh! My bad for misunderstanding.
- pjmlp 3y ago> C#, for example, does not necessarily store value types on the stack It does if you use the right set of keywords, learn them.