DIP 1016 should use expression lowering, not statement lowering

Rubn where at is.this
Tue Jan 29 20:45:32 UTC 2019


On Tuesday, 29 January 2019 at 15:44:02 UTC, Nicholas Wilson 
wrote:
> On Tuesday, 29 January 2019 at 11:52:40 UTC, Andrei 
> Alexandrescu wrote:
>> While writing this example:
>>
>> int[] a = cast(int[]) alloc.allocate(100 * int.sizeof);
>> if (alloc.reallocate(a, 200 * int.sizeof))
>> {
>>     assert(a.length == 200);
>> }
>>
>> =====>
>>
>> int[] a = cast(int[]) alloc.allocate(100 * int.sizeof);
>> void[] __temp0 = a;
>> if (alloc.reallocate(__temp0, 200 * int.sizeof)
>> {
>>     assert(a.length == 200);
>> }
>>
>> I noticed a problem - the lowering as informally described in 
>> DIP 1016 makes it difficult to figure how function calls 
>> present in control statements like if, while, etc. should 
>> behave. Where should the temporary go? An expression-based 
>> lowering clarifies everything. A statement-based lowering 
>> would need to work on a case basis for all statements 
>> involving expressions.
>
> On the contrary, an expression lowering cannot inject temporary 
> declarations and is impossible.
>
> The correct lowering in the case for `if` & friends follows the 
> form of C++ initialiser conditions(?) i.e:
>
>  if (auto val = expr(); val) { ... },
>
>  or the slightly more ugly valid D:
>
>  if ((){return expr(); }()) { ... }
>
> this lambdification will work for just about anything: if, 
> while, assert...

If it a condition then you can do the following in C++:

if(int* val = expr()) {
    // use val, not nullptr
}

Where it is useful is in the following case:

if(int val = expr(); val != -1) {

}

D follows C++'s construct for initializing a variable in control 
blocks. The only exception I think is for switch.

switch(int val = expr()) // ok in C++, not ok in D
{
}


More information about the Digitalmars-d-announce mailing list