On Friday, 26 August 2016 at 14:12:24 UTC, Basile B. wrote:
On Friday, 26 August 2016 at 14:03:13 UTC, Meta wrote:
On Friday, 26 August 2016 at 10:51:15 UTC, Johan Engelen wrote:
On Thursday, 25 August 2016 at 14:42:28 UTC, Basile B. wrote:

I'll add

* create temporaries based on the const function attribute.

Struct method constness (as in your example) does not mean that the return value is constant when calling it twice in a row. As pointed out by others, the function needs to be pure. Dlang pureness is not a strong enough guarantee.
For example, this is explicitly allowed by the spec:
```
pure int foo()
{
debug writeln("in foo()"); // ok, impure code allowed in debug statement
    return 1;
}
```
That makes it illegal to transform `foo()+foo()` to `a=foo(); a+a`, at least in debug builds.

David discusses your proposed optimization, and why it cannot be done in general (!) on Dlang pure functions.
http://klickverbot.at/blog/2012/05/purity-in-d/

-Johan

Here's an example that doesn't even need to use debug statements, and is perfectly legal.

class Test
{
    int n;

    void setN(int val) pure
    {
        n = val;
    }

    int getN() const pure
    {
        return n;
    }
}

import std.stdio;

void main()
{
    auto t = new Test();
    writeln(t.getN()); //Prints 0
    t.setN(1);
    writeln(t.getN()); //Prints 1
}

That's another story. Of course the optimization pass for this should check that **ALL** the calls to Test in a sub program (or in this scope if you want) are const... Which is not the case here.

void foo(Bar bar)
{
foreach(i; 0 .. bar.length) // bar.length can be evaluated once
    {
       stuffA.a = bar[i].propertyA // bar[i] can be cached
       stuffB.b = bar[i].propertyB // to get propertyB
    }
}

with

interface Bar
{
    size_t length() pure const;
    Stuff opIndex(size_t) pure const;
}

Reply via email to