Home > Software design >  Why is memory storage location linked to class/struct?
Why is memory storage location linked to class/struct?

Time:06-18

C# is, unlike C , a language that hides technical stuff from the developer. No pointers (except in unsafe code) and garbage collection are examples of this. As I understand, C# wants the developer to focus only on the concepts and not the underlying architecture, memory handling etc..

But then, why does the developer have to decide where an object is to be stored? For class it is always on the heap, for struct it is either on the stack (if local variable) or inline (if member of an object).

Isn't that something the compiler could figure out either based on the class definition (it could estimate needed memory space and decide heuristically based on that) or based on the context a given instance is in (is it a local variable in a function, then stack; is it more global, then heap; is it member of an object, then base decision on its estimated memory space)?


PS: I know class and struct have more differences than that, namely reference equality versus value equality, but this is not point of my question. (And for those aspects, other solutions could be found to unlink these properties from the decision class/struct.)

CodePudding user response:

Your question is not valid (I mean in a logical way) because it depends on a false premise:

The developper cannot really decide where an object is to be stored, because this is an implementation detail.

See this answer discussing struct on heap or stack,

or this question: C# structs/classes stack/heap control?

The first links to Eric Lippert's blog. Here is an extract:

Almost every article I see that describes the difference between value types and reference types explains in (frequently incorrect) detail about what “the stack” is and how the major difference between value types and reference types is that value types go on the stack. I’m sure you can find dozens of examples by searching the web.

I find this characterization of a value type based on its implementation details rather than its observable characteristics to be both confusing and unfortunate. Surely the most relevant fact about value types is not the implementation detail of how they are allocated, but rather the by-design semantic meaning of “value type”, namely that they are always copied “by value” . If the relevant thing was their allocation details then we’d have called them “heap types” and “stack types”. But that’s not relevant most of the time. Most of the time the relevant thing is their copying and identity semantics.

I regret that the documentation does not focus on what is most relevant; by focusing on a largely irrelevant implementation detail, we enlarge the importance of that implementation detail and obscure the importance of what makes a value type semantically useful. I dearly wish that all those articles explaining what “the stack” is would instead spend time explaining what exactly “copied by value” means and how misunderstanding or misusing “copy by value” can cause bugs.

CodePudding user response:

C# is, unlike C , a language that hides technical stuff from the developer

I do not think this is a fair characterization of c#. There is plenty of technical details a c# developer has to be aware of, and there are plenty of languages work on a much higher abstraction level. I think it would be more fair to say that C# aims to make it easy to write good, working code. Sometimes called "The pit of success" by Eric Lippert. See also C and the pit of despair.

Ideally you would just write code that describes the problem, and let the compiler sort out anything that has to do with performance. But writing compilers is hard, especially when you have a hard time constraint since you are compiling just in time. While language is theoretically unrelated to performance, practice show that higher level languages tend to be more difficult to optimize.

While there are important semantic differences between a struct and a class, the main reason to chose one or the other usually comes down to performance, and the performance is directly related to how they are stored and passed around. You would typically avoid many small objects, or passing around huge structs.

As a comparison, Java is very similar to C#, and did just fine without value types for many years. It seems however like they have or will introduce one to reduce the overhead of creating objects.

why does the developer have to decide where an object is to be stored?

The simple answer seem to be that determining the optimal storage location is difficult for the compiler to do. Letting the developer hint how the type is used helps improve performance for some situations and allow C# to be used in in situations where it would otherwise be unsuitable for. At the cost of making the language more complex and more difficult to learn.

  • Related