Regarding ref results
John Colvin via Digitalmars-d
digitalmars-d at puremagic.com
Wed Apr 30 04:10:01 PDT 2014
On Wednesday, 30 April 2014 at 10:22:45 UTC, bearophile wrote:
> - You need to define the return variable before the function,
> this is not handy for UFCS chains;
> - You also need to define the type of the result before calling
> the function. Here I have found such type using
> ParameterTypeTuple, but this is not so handy, and if the
> function becomes a template, you also need to instantiate it to
> find the argument type.
Assuming a static array is considered to be a normal aggregate,
the System V ABI defines some of this problem away.
int[10] foo()
{
int[10] a;
//fill a
return a;
}
void bar()
{
foo();
}
becomes assembly equivalent to this, assuming a sensible (not
necessarily very clever) compiler:
void foo(int* ret)
{
int[10] a;
//fill a
ret[0 .. 10] = a[];
}
void bar()
{
int[10] a;
foo(a.ptr);
}
The memory is allocated on stack of caller, and then it passes
the base address in %edi
Perhaps I'm being naive, but it should be trivial for the
optimiser to produce something like:
void foo(int* ret)
{
ret[0 .. 10] = 0; //pessimistic, sometimes elidable.*
//fill ret as if it was an int[10]
}
void bar()
{
int[10] a;
foo(a.ptr);
}
*especially when inlined.
I'm not so familiar with other ABIs, but there are really only 3
choices: 1) allocate in caller, 2) memcopy or 3) return in
multiple registers. I doubt anyone uses 2, 1 is what we see above
and 3 is very cheap (register moves normally cost little).
More information about the Digitalmars-d
mailing list