December 24, 2012
On Monday, 24 December 2012 at 19:09:35 UTC, Jonathan M Davis wrote:
> On Monday, December 24, 2012 20:03:24 monarch_dodra wrote:
>> Hum... Indeed, it takes by ref *and* returns by ref. Passing in
>> to out a const ref is *the* smoking gun. Working with D has
>> gotten me used to functions that take by value and return by
>> value...
>> 
>> Snap. You got me.
>
> It wouldn't matter if the function accepted its argument by value...
> 
> - Jonathan M Davis

well, if the function took by value, and returned by ref, then it would be just plain *wrong*, no conditions, so that did not even cross my mind.

I *thought* min took by ref, and returned by value, hence my confusion to the example. I'm legitimatly surprised to learn that it works that way, specifically because I've learned to NEVER return by ref an input argument exactly because of this...

Side question, is this legal?

"int a = min(min(1,2), min(3,4));"

How long do those temps last? I like this piece of code, because the previous had that fishy "const int&", which raises eyebrows, but I think this example could blindsind even the most careful programmer.

EDIT: In this specific example, those might be statics, so the code would be legal, but what if we replace those ints with "foo()"s ?
December 24, 2012
On Monday, December 24, 2012 21:42:09 monarch_dodra wrote:
> Side question, is this legal?
> 
> "int a = min(min(1,2), min(3,4));"
> 
> How long do those temps last? I like this piece of code, because the previous had that fishy "const int&", which raises eyebrows, but I think this example could blindsind even the most careful programmer.
> 
> EDIT: In this specific example, those might be statics, so the code would be legal, but what if we replace those ints with "foo()"s ?

As I understand it, temporaries last for the duration of the statement that they're used it. So, the example would be legal and completely safe.

- Jonathan M Davis
December 24, 2012
On 12/24/12 1:49 PM, Jonathan M Davis wrote:
> On Monday, December 24, 2012 13:45:10 Andrei Alexandrescu wrote:
>> The very binding of rvalues to const ref would allow that breakage. We
>> can't allow that to happen.
>
> But it's only bound for the length of the statement. After that, the binding
> can no longer exist (as the binding was a function parameter). And as I
> understand it, temporaries only go out of scope once the statement has
> completed. So,
>
> foo(bar(min(5, 7)));
>
> wouldn't be a problem no matter what bar or foo did, because no reference to
> 5, 7, or the return values of any of the functions could be kept.

Actually D's rules are different from C++'s in that regard; Walter mentioned D is more sanguine about destroying data. I'll check with him.

> It's being
> able to do
>
> const int&  i = foo(bar(min(5, 7)));
>
> which would allow a reference to be kept around, which D disallows.

I now see what you mean, thanks. We need to disallow taking the address of that ref, but that's already planned.


Andrei
December 24, 2012
On 12/24/12 2:46 PM, anonymous wrote:
> On Monday, 24 December 2012 at 18:50:12 UTC, Jonathan M Davis wrote:
>> const int& i = foo(bar(min(5, 7)));
>>
>> which would allow a reference to be kept around, which D disallows.
>
> Does it?
>
> const(int)* i = &foo(bar(min(5, 7)));

We plan to forbid that.

Andrei
December 24, 2012
On Monday, December 24, 2012 16:08:36 Andrei Alexandrescu wrote:
> On 12/24/12 1:49 PM, Jonathan M Davis wrote:
> > On Monday, December 24, 2012 13:45:10 Andrei Alexandrescu wrote:
> Actually D's rules are different from C++'s in that regard; Walter mentioned D is more sanguine about destroying data. I'll check with him.

Well, that could be a problem.

> > It's being
> > able to do
> > 
> > const int&  i = foo(bar(min(5, 7)));
> > 
> > which would allow a reference to be kept around, which D disallows.
> 
> I now see what you mean, thanks. We need to disallow taking the address of that ref, but that's already planned.

Actually, one problem did occur to me after thinking about this some more.

ref int foo(ref int i)
{
    return i;
}

ref int bar(int j)
{
    return foo(j);
}

While the ref returned by bar can't be saved without being copied, it's returning a ref which isn't valid once bar has returned, since it was a function parameter which was not ref. The same would occur if you did

ref int baz()
{
    int i;
    return foo(i);
}

The ref has managed to basically do what happens with & and pointers, and it's essentially the same as

int* foo(int* i)
{
    return i;
}

int* bar(int j)
{
    return foo(&j);
}

You have an escaping reference. So, while the min example would be valid, because ref was used througout, if any part of the chain passed by value or if it was a local variable inside one of those functions which was returned by ref, then we're in trouble. And auto ref will have exactly the same problem. The fact that you can both pass by ref screws things up. If that were illegal, then we'd be okay, but it's not illegal, and it would be problematic if it were, since we'd end up with lots of unnecessary copies in quite a few cases.

I suppose that we could disallow returning by ref unless the value being returned was an actual variable (as opposed to the return value of another function which returned by ref), but I don't know how restrictive that would be.

Certainly, as things stand, the code above that uses ref is doing what would currently be considered @safe code even though it's actually unsafe. We definitely need to work through this some more and figure out what should and shouldn't be valid and what we can and can't make @safe.

- Jonathan M Davis
December 26, 2012
Quick question: what is the state of things with dmd 2.061 and I see that right, that "auto ref" is more complicated than first thought? :/
December 26, 2012
On Wednesday, December 26, 2012 10:43:53 Namespace wrote:
> Quick question: what is the state of things with dmd 2.061

AFAIK, it's exactly the same as it was in 2.060.

- Jonathan M Davis
December 26, 2012
On Wednesday, 26 December 2012 at 22:33:38 UTC, Jonathan M Davis wrote:
> On Wednesday, December 26, 2012 10:43:53 Namespace wrote:
>> Quick question: what is the state of things with dmd 2.061
>
> AFAIK, it's exactly the same as it was in 2.060.
>
> - Jonathan M Davis

I mean, when it comes out. But that has now done. ;)
December 28, 2012
In consideration that Andrei said that the implementation of "auto ref" for none-template functions are relatively easy and that until now only the first beta of 2.061 came out: How likely is it that "auto ref" will implemented in this release? Maybe an official statement would be good.

Purely out of interest, because only then this release would really be useful for me (and maybe even for other).
But of course I know, that I am completely irrelevant. ;)
December 28, 2012
Namespace:

> How likely is it that "auto ref" will implemented in this release?

Walter wants to release 2.061 "soon". So maybe that's for the successive (unstable?) version of the compiler.

Bye,
bearophile