www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Static Arrays: Behaviour of Passing & Returning

reply Quantum Nerd <qnerd posteo.org> writes:
Hello everybody,

I am fairly new to the D language,
and I've been trying to understand the behaviour
of passing arrays to functions, especially also
static arrays.

There is an example that puzzles me:

import std.stdio;

double[3] sqr( double[3] v ) {
   double[3] r;
   writefln( "v (%20s) : %s", typeof(v).stringof, &v[0] );
   writefln( "r (%20s) : %s", typeof(r).stringof, &r[0] );
   r[] = v[] * v[];
   return r;
}

void main() {
   double[3] a = [1.0, 2.0, 3.0 ];
   double[3] b = sqr(a);
   writefln( "a (%20s) : %s", typeof(a).stringof, &a[0] );
   writefln( "b (%20s) : %s", typeof(b).stringof, &b[0] );

   double[3] c; c = sqr(a);
   writefln( "c (%20s) : %s", typeof(c).stringof, &c[0] );
}


with the output:
v (           double[3]) : 7FFD0D3874E0
r (           double[3]) : 7FFD0D387548
a (           double[3]) : 7FFD0D387528
b (           double[3]) : 7FFD0D387548
v (           double[3]) : 7FFD0D3874E0
r (           double[3]) : 7FFD0D387588
c (           double[3]) : 7FFD0D387568


According to the documentation, static arrays are of value type.

How is it possible that b in main() and r in the function occupy 
the same memory?
I would expect the same behaviour as with c.

Can somebody with more experience shed some light on this?


Thanks in advance,

qnerd
Mar 21 2018
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Wednesday, 21 March 2018 at 12:01:01 UTC, Quantum Nerd wrote:
 How is it possible that b in main() and r in the function 
 occupy the same memory?
 I would expect the same behaviour as with c.

 Can somebody with more experience shed some light on this?
I'm pretty sure you're seeing NRVO - Named Return Value Optimization. Also called copy elision: https://en.wikipedia.org/wiki/Copy_elision The compiler sees that when you return r, it's immediately assigned to b. Since it's a waste of cycles to allocate twice and copy the values, the function is told where the result will end up, and writes it there immediately. The reason you don't see that with c is that the compiler isn't very smart, especially not with optimizations turned off, so it doesn't know for sure that it can safely overwrite the values already in c at that point. -- Simen
Mar 21 2018
parent Quantum Nerd <qnerd posteo.org> writes:
On Wednesday, 21 March 2018 at 12:15:13 UTC, Simen Kjærås wrote:

 I'm pretty sure you're seeing NRVO - Named Return Value 
 Optimization. Also called copy elision:
 https://en.wikipedia.org/wiki/Copy_elision

 The compiler sees that when you return r, it's immediately 
 assigned to b. Since it's a waste of cycles to allocate twice 
 and copy the values, the function is told where the result will 
 end up, and writes it there immediately.

 The reason you don't see that with c is that the compiler isn't 
 very smart, especially not with optimizations turned off, so it 
 doesn't know for sure that it can safely overwrite the values 
 already in c at that point.
Thanks a lot, that explains things. I was really surprised, as I had compiler optimizations in mind before I posted. I ran the tests without any optimization using ldc2 -g -O0, but the outcome was the same. Thanks for your help, qnerd
Mar 22 2018