Example of the perils of binding rvalues to const ref
IgorStepanov via Digitalmars-d
digitalmars-d at puremagic.com
Wed Sep 17 12:28:56 PDT 2014
On Wednesday, 17 September 2014 at 15:03:12 UTC, Andrei
Alexandrescu wrote:
> On 9/17/14, 3:03 AM, IgorStepanov wrote:
>> BTW. About r-values:
>>
>> void fun(S s)
>> {
>> fun2(s); //pass s by value.
>> }
>>
>> Now, compiler inserts postblit call before func2 call and dtor
>> before
>> end of fun.
>
> Is the call to dtor part of fun(), or part of fun()'s call
> sequence? I've always meant to look at that. LMK if you know
> for sure.
Dtor call is a part of fun().
I've written test code...
struct Foo
{
this(int i)
{
}
this(this)
{
}
~this()
{
}
}
void calledFunc(Foo probe)
{
}
void main()
{
calledFunc(Foo(42));
}
... add a trace output into Statement_toIR::visit(ExpStatement
*s) ...
printf("ExpStatement::toIR(), exp = %s in %s\n", s->exp ?
s->exp->toChars() : "", irs->symbol ? irs->symbol->toChars() :
"NULL");
... and got:
ExpStatement::toIR(), exp = probe.~this() in calledFunc
>> However, it is able to doesn't it, because after fun2 call,
>> s isn't used.
>> Thus, we can implement last postblit optimization:
>> If compiler want to insert postblit, and object is't used
>> after this
>> postblit, compiler is able to doesn't generate postblit and
>> last dtor
>> calls.
>> Is there limitation of this optimization?
>> It may 90 percent to solve a r-value ref task.
>
> I think rvalues are already not postblitted into functions.
> Indeed more postblits can be optimized away for variables are
> are last used in a function call.
>
>
> Andrei
Yes, rvalues aren't posblitted. However I want and I can't
deliver without postblits rvalue from first call (of constructor
or factory function) through intermediate calls to the final
place of stay.
struct AA(Key, Value)
{
this(T...)(T args)
{
buckets.length = T.length;
foreach (i; Step2Tuple!(T.length))
{
alias key = args[i];
alias value = args[i+1];
size_t key_hash = hashOf(key);
size_t idx = key_hash % T.length;
auto e = new Entry(key_hash, key, value,
impl.buckets[idx]);
buckets[idx] = e;
}
}
...
private static struct Entry
{
size_t hash;
Key key;
Value value;
Entry* next;
}
Entry*[] buckets;
}
AA!(Key, Value) aaLiteral(Key, Value, T...)(auto ref T args)
{
return AA!(Key, Value)(args);
}
....
//somewhere in user code:
auto aa = aaLiteral!(Foo, int)(Foo(1), 1, Foo(2), 2); //postblits
aren't called.
I want to place Foo(1) to buckets[nn].key without postblit call.
Compiler can't help me now, however, I think, It can do it
without language change.
More information about the Digitalmars-d
mailing list