www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is it's correct to say that ALL types that can grow are place on heap?

reply Suliman <evermind live.ru> writes:
Is it's correct to say that ALL types that can grow are place on 
heap and types that not growing (int, char, pointer) are place on 
stack?

Or there is some exceptions?

Is there any tools that can visualize place of data in memory?
Sep 08 2018
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 09/08/2018 02:19 AM, Suliman wrote:
 Is it's correct to say that ALL types that can grow are place on heap
 and types that not growing (int, char, pointer) are place on stack?
The question is not that simple. :) First, there is also the area used for objects that are static and object that are defined at module scope. That is different from both the call stack and the heap. Let's ignore them... There are automatic objects like local variables inside a function and function parameters. They normally live on the stack. (However, the compiler may pass some parameters in CPU registers without allocating any memory at all.) As you say, whenever memory is dynamic in nature e.g. we don't know the size before hand, the memory is normally allocated from the heap. However, heap can be used for allocating even an int: import std.stdio; void main() { auto p = new int(42); writeln(p); writeln(*p); } Although the memory used for the elements of a dynamic array is on the heap, the slice itself is usually on the stack: import std.stdio; void main() { auto arr = [ 42 ]; writeln("Local slice variable is at ", &arr); // stack writeln("The elements of the array are at ", arr.ptr); // heap } Then there are member variables of a user-defined type: Obviously, those variables are wherever the actual object lives.
 Or there is some exceptions?

 Is there any tools that can visualize place of data in memory?
I think there are some debuggers that visualize data like that but I don't have experience with those. Ali
Sep 08 2018
parent reply Timoses <timosesu gmail.com> writes:
On Saturday, 8 September 2018 at 22:51:17 UTC, Ali Çehreli wrote:
 On 09/08/2018 02:19 AM, Suliman wrote:
 Is it's correct to say that ALL types that can grow are place
on heap
 and types that not growing (int, char, pointer) are place on
stack? The question is not that simple. :) First, there is also the area used for objects that are static and object that are defined at module scope. That is different from both the call stack and the heap. Let's ignore them... There are automatic objects like local variables inside a function and function parameters. They normally live on the stack. (However, the compiler may pass some parameters in CPU registers without allocating any memory at all.)
Is this why it is said that passing parameters by value can be more efficient? Cause for a ref parameter it would require passing the address which would require to be allocated? Aww, I really would love some insights into function parameter passing. Why is it said that passing by value can be more efficient at times? Since it is also said that passing large structs by value can be expensive, why then would it not be cheaper to ALWAYS pass everything by reference? What mechanism is behind the scene that follows one to reason that sometimes passing by value is less expensive? I get that passing an int by reference would cause indirections which need to be resolved whereas passing the int by value is just one copy (I guess). This topic kinda seemed fit for my question that I was carrying around for some time.
Sep 11 2018
next sibling parent reply drug <drug2004 bk.ru> writes:
11.09.2018 13:11, Timoses пишет:
 
 Is this why it is said that passing parameters by value can be more 
 efficient?
 Cause for a ref parameter it would require passing the address which 
 would require to be allocated?
 
 Aww, I really would love some insights into function parameter passing. 
 Why is it said that passing by value can be more efficient at times?
 Since it is also said that passing large structs by value can be 
 expensive, why then would it not be cheaper to ALWAYS pass everything by 
 reference? What mechanism is behind the scene that follows one to reason 
 that sometimes passing by value is less expensive?
 
 I get that passing an int by reference would cause indirections which 
 need to be resolved whereas passing the int by value is just one copy (I 
 guess).
 
 
 This topic kinda seemed fit for my question that I was carrying around 
 for some time.
 
 
If data size is less or equal to total size of available registers (that can be used to pass values) than passing by value is more efficient. Passing data with size less than register size by reference isn't efficient because you pass pointer (that has register size) and access memory using it.
Sep 11 2018
parent reply Timoses <timosesu gmail.com> writes:
On Tuesday, 11 September 2018 at 12:07:14 UTC, drug wrote:
 If data size is less or equal to total size of available 
 registers (that can be used to pass values) than passing by 
 value is more efficient. Passing data with size less than 
 register size by reference isn't efficient because you pass 
 pointer (that has register size) and access memory using it.
Thank you! So if I pass by reference it will ALWAYS use the address in memory to fetch the data, whereas passing it by value enables the (compiler?..) to use the register which has already loaded the data from memory (stack for example)?
Sep 12 2018
parent reply drug <drug2004 bk.ru> writes:
12.09.2018 15:14, Timoses пишет:
 On Tuesday, 11 September 2018 at 12:07:14 UTC, drug wrote:
 If data size is less or equal to total size of available registers 
 (that can be used to pass values) than passing by value is more 
 efficient. Passing data with size less than register size by reference 
 isn't efficient because you pass pointer (that has register size) and 
 access memory using it.
Thank you! So if I pass by reference it will ALWAYS use the address in memory to fetch the data, whereas passing it by value enables the (compiler?..) to use the register which has already loaded the data from memory (stack for example)?
Honestly, I'm not an expert in this domain, but I think so.
Sep 12 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 13/09/2018 2:34 AM, drug wrote:
 12.09.2018 15:14, Timoses пишет:
 On Tuesday, 11 September 2018 at 12:07:14 UTC, drug wrote:
 If data size is less or equal to total size of available registers 
 (that can be used to pass values) than passing by value is more 
 efficient. Passing data with size less than register size by 
 reference isn't efficient because you pass pointer (that has register 
 size) and access memory using it.
Thank you! So if I pass by reference it will ALWAYS use the address in memory to fetch the data, whereas passing it by value enables the (compiler?..) to use the register which has already loaded the data from memory (stack for example)?
Honestly, I'm not an expert in this domain, but I think so.
Recently used areas of the stack will be available in the cache in most cases. The issue with passing by reference is it increases the indirection (number of pointers) that it must go through to get to the raw bytes. This is why classes are bad but structs are good. Even if the struct is allocated on the heap and you're accessing it via a pointer.
Sep 12 2018
parent reply Timoses <timosesu gmail.com> writes:
On Wednesday, 12 September 2018 at 14:46:22 UTC, rikki cattermole 
wrote:
 On 13/09/2018 2:34 AM, drug wrote:
 12.09.2018 15:14, Timoses пишет:
 On Tuesday, 11 September 2018 at 12:07:14 UTC, drug wrote:
 If data size is less or equal to total size of available 
 registers (that can be used to pass values) than passing by 
 value is more efficient. Passing data with size less than 
 register size by reference isn't efficient because you pass 
 pointer (that has register size) and access memory using it.
Thank you! So if I pass by reference it will ALWAYS use the address in memory to fetch the data, whereas passing it by value enables the (compiler?..) to use the register which has already loaded the data from memory (stack for example)?
Honestly, I'm not an expert in this domain, but I think so.
Recently used areas of the stack will be available in the cache in most cases. The issue with passing by reference is it increases the indirection (number of pointers) that it must go through to get to the raw bytes. This is why classes are bad but structs are good. Even if the struct is allocated on the heap and you're accessing it via a pointer.
This sounds like classes should never be used.. I don't recall right now what issues I'm usually encountering with structs that make me switch to classes (in D). So passing by reference is generally only applicable (logical) to structs and non-reference types + only makes sense when the function being called is supposed to change the referenced value without returning it. Except, as Steven pointed out in his post when dealing with large lvalue structs. This all seems quite complicated to "get right" when writing code. I'm sure there are compiler optimizations run on this? Or is that not possible due to the nature of difference in ref and value passing. Anyhow, thanks for the answers! I bet it's possible to write books on this topic.. Or just mention ones that already were written : ~D.
Sep 12 2018
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 13/09/2018 3:22 AM, Timoses wrote:
 On Wednesday, 12 September 2018 at 14:46:22 UTC, rikki cattermole wrote:
 On 13/09/2018 2:34 AM, drug wrote:
 12.09.2018 15:14, Timoses пишет:
 On Tuesday, 11 September 2018 at 12:07:14 UTC, drug wrote:
 If data size is less or equal to total size of available registers 
 (that can be used to pass values) than passing by value is more 
 efficient. Passing data with size less than register size by 
 reference isn't efficient because you pass pointer (that has 
 register size) and access memory using it.
Thank you! So if I pass by reference it will ALWAYS use the address in memory to fetch the data, whereas passing it by value enables the (compiler?..) to use the register which has already loaded the data from memory (stack for example)?
Honestly, I'm not an expert in this domain, but I think so.
Recently used areas of the stack will be available in the cache in most cases. The issue with passing by reference is it increases the indirection (number of pointers) that it must go through to get to the raw bytes. This is why classes are bad but structs are good. Even if the struct is allocated on the heap and you're accessing it via a pointer.
This sounds like classes should never be used.. I don't recall right now what issues I'm usually encountering with structs that make me switch to classes (in D).
Nah, this is cycle counting aka don't worry about it if you're not doing anything super high performance.
Sep 12 2018
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 9/11/18 3:11 AM, Timoses wrote:
 Aww, I really would love some insights into function parameter passing. 
 Why is it said that passing by value can be more efficient at times?
 Since it is also said that passing large structs by value can be 
 expensive, why then would it not be cheaper to ALWAYS pass everything by 
 reference? What mechanism is behind the scene that follows one to reason 
 that sometimes passing by value is less expensive?
So consider that accessing a struct from the function is cheaper when it is passed by value -- you have one offset from the stack pointer, and that's it. Vs. going through the stack pointer to get the reference, and then dereferencing that. In addition, passing a large struct by value can be as cheap or even cheaper if you can construct the value right where it is going to be passed. In other words, you don't need to make *any* copies. This can be true for rvalues that are passed by value, but not lvalues. So in addition to register passing, there are other benefits to consider. -Steve
Sep 12 2018