February 05, 2013
On Mon, 04 Feb 2013 18:18:16 -0500, Walter Bright <newshound2@digitalmars.com> wrote:

> On 2/4/2013 6:05 AM, Andrei Alexandrescu wrote:
>> Couldn't AddressOf use "&(" + exp + ")"?
>>
>> I thought more about this. The problem remains even without @property, due to
>> optional parens in function invocation. Consider:
>>
>> ref int fun() { ... }
>> auto p1 = &fun;
>> auto p2 = &(fun);
>> auto p3 = &(fun());
>>
>> What are the types of the three? The optional parens in invocation require some
>> disambiguation. I think the sensible disambiguation is to have &fun take the
>> address of fun and the other two take the address of fun's result.
>
> The only time it is valid to take the address of a function's return value is if the function returns a ref.
>
> But I also would think that it's a suspicious practice to take the address of a ref. We've disallowed it in other circumstances, why allow it here? If a function intends for someone to take the address of the return ref, shouldn't the function return a pointer instead?

I'd agree with you if we could have ref variables.  In some cases, taking the address is the ONLY option.

-Steve
February 05, 2013
On Mon, 04 Feb 2013 17:23:25 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 2/4/13 11:01 AM, Steven Schveighoffer wrote:
>> @property int foo();
>>
>> auto x = &foo; // error
>> int delegate() x = &foo; // ok
>
> That's an interesting idea. I'm a bit weary about it though. At least for properties I'm inclined toward starting real tight with address-of disabled and relax the rules later.

Did you mean wary?

In any case, that certainly is a defensible plan.  We do have the workaround of declaring an extra delegate (and someone probably can come up with some template magic which does it).  If we make it illegal, it gives us the option of coming up with a good solution later if needed.

-Steve
February 05, 2013
On 2/5/13 11:44 AM, Steven Schveighoffer wrote:
> On Mon, 04 Feb 2013 18:18:16 -0500, Walter Bright
> <newshound2@digitalmars.com> wrote:
>
>> On 2/4/2013 6:05 AM, Andrei Alexandrescu wrote:
>>> Couldn't AddressOf use "&(" + exp + ")"?
>>>
>>> I thought more about this. The problem remains even without
>>> @property, due to
>>> optional parens in function invocation. Consider:
>>>
>>> ref int fun() { ... }
>>> auto p1 = &fun;
>>> auto p2 = &(fun);
>>> auto p3 = &(fun());
>>>
>>> What are the types of the three? The optional parens in invocation
>>> require some
>>> disambiguation. I think the sensible disambiguation is to have &fun
>>> take the
>>> address of fun and the other two take the address of fun's result.
>>
>> The only time it is valid to take the address of a function's return
>> value is if the function returns a ref.
>>
>> But I also would think that it's a suspicious practice to take the
>> address of a ref. We've disallowed it in other circumstances, why
>> allow it here? If a function intends for someone to take the address
>> of the return ref, shouldn't the function return a pointer instead?
>
> I'd agree with you if we could have ref variables. In some cases, taking
> the address is the ONLY option.

Walter and I reviewed the discussion and had a long talk. We are very seriously considering banning the use of & against a ref result from a function (and actually ref parameters and even struct members in @safe code). One would still be able to take the address of a field in a class because that's assumed to live on the GC heap.

To get the address of an object in @system code without resorting to operator& at all, we're considering adding a stdlib function implemented like this (there are several other ways, this is just for illustration):

@system T* addressOf(T)(ref T obj)
{
    static T* id(T* p) { return p; }
    auto idr = cast(T* function(ref T)) id;
    return idr(obj);
}

I have a DIP in the making that makes "ref" entirely sealed, i.e. it makes it impossible to have a dangling ref in safe code. If that DIP gets approved, then DIP23 gets considerably simplified because operator& won't be applicable to the result of a function anymore.


Andrei
February 05, 2013
Andrei Alexandrescu:

> One would still be able to take the address of a field in a class because that's assumed to live on the GC heap.

Maybe some people want to allocate many small class instances on the stack.

Bye,
bearephile
February 05, 2013
On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Walter and I reviewed the discussion and had a long talk. We are very seriously considering banning the use of & against a ref result from a function (and actually ref parameters and even struct members in @safe code). One would still be able to take the address of a field in a class because that's assumed to live on the GC heap.

What about structs that live on the heap?  e.g. a struct element of an array, or a struct member of a class instance.

I think the point about @safe code is moot, aren't pointers disallowed in safe code anyway?

> To get the address of an object in @system code without resorting to operator& at all, we're considering adding a stdlib function implemented like this (there are several other ways, this is just for illustration):
>
> @system T* addressOf(T)(ref T obj)
> {
>      static T* id(T* p) { return p; }
>      auto idr = cast(T* function(ref T)) id;
>      return idr(obj);
> }


I think a cast would be sufficient:

cast(int *)(&refparam); // understood that a cast is required

To jump through this machinery to turn a reference into a, um... reference, seems like a huge waste of code space and resources.

-Steve
February 05, 2013
On Tue, Feb 05, 2013 at 02:05:24PM -0500, Steven Schveighoffer wrote:
> On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> 
> >Walter and I reviewed the discussion and had a long talk. We are very seriously considering banning the use of & against a ref result from a function (and actually ref parameters and even struct members in @safe code). One would still be able to take the address of a field in a class because that's assumed to live on the GC heap.
> 
> What about structs that live on the heap?  e.g. a struct element of an array, or a struct member of a class instance.
> 
> I think the point about @safe code is moot, aren't pointers disallowed in safe code anyway?
[...]

AFAIK, pointers are allowed in @safe code as long as no type casts or pointer arithmetic are performed.


T

-- 
There is no gravity. The earth sucks.
February 05, 2013
On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Walter and I reviewed the discussion and had a long talk. We are very seriously considering banning the use of & against a ref result from a function (and actually ref parameters and even struct members in @safe code). One would still be able to take the address of a field in a class because that's assumed to live on the GC heap.

Back to the problem I stated, how does one do this:

ref A foo();

ref A bar();

A *a;

if(condition)
   a = &foo();
else
   a = &bar();

// use a for a few lines

I can see a possible solution but it's not pretty:

void processA(ref A a)
{
   // lines that deal with a here
}

if(condition)
  processA(foo());
else
  processA(bar());

But this kind of seems hacky.  Why should I have to declare a function just to keep a persistent reference to a return value for the scope of my function?  Not only is is awkward, there is a performance hit in that I have to call another function.

Note also that this doesn't fix memory issues:

struct S
{
  ref S self() {return this;}
}

ref S bad()
{
   S s;
   return s.self();
}

Which I believe would be valid still with your rules.

-Steve
February 05, 2013
On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> Walter and I reviewed the discussion and had a long talk. We are very seriously considering banning the use of & against a ref result from a function (and actually ref parameters and even struct members in @safe code). One would still be able to take the address of a field in a class because that's assumed to live on the GC heap.

Thinking about this some more, would this be allowed:

@trusted T *getAddr(T)(ref T obj) { return &obj; } // allowed?  You said only @safe code would disallow address of ref parameters

-Steve
February 05, 2013
On Tuesday, 5 February 2013 at 08:39:15 UTC, Dmitry Olshansky wrote:
> On 02/05/2013 02:28 AM, Andrei Alexandrescu wrote:> On 2/4/13 2:04 PM, Jonathan M Davis wrote:
> >> We could save a lot of boilerplate code if we can simply
> make it
> >> variables and
> >> property functions guaranteed to be swappable without
> breaking code.
> >
> > I think this is quite powerful. The way we can do this is by
> making
> > properties emulate a subset of actual variables.
> >
>
> This is the primary real-world proble to solve.
> If tackle it right  we'd secure a sizable flow of Java
> converts simply because of this feature alone ;)
>
> More seriously I believe it's worth noting that properties can't emulate (in principle) exactly one aspect of variable - taking address
> as a pointer. Honestly I can't see a way to overcome it without introducing a user-defined way to impose this restriction on a field of a struct/class.

I'm not really sure which part of my article you are addressing here, but allowing  'opAddress' is available as a last resort. Also note that I had proposed 'cast(function)' instead of '&' to get the top-level function, which, unlike '&', can give: 'Error: not castable as a function'

> Then keeping in mind __traits I have the following clause to add to the current proposal:
>
> Inside of aggregate a field marked with @property indicate is semantically equivalent to compiler wrapping it with trivial getter and setter. Example:
> struct Foo{
> @property T x;
> }
>
> treated  semantically as if:
> T __x; // hidden by compiler
> //templated to have deduced safe, pure, nothrow
> @property T x()()inout{ return x; }
> @property void x()(T val){ x = val; }
>
> ---
> Dmitry Olshansky

While I appreciate your responding to my post, I'm a little confused which of its points you are addressing here.
February 05, 2013
05-Feb-2013 23:37, Zach the Mystic пишет:
[snip]
>
> While I appreciate your responding to my post, I'm a little confused
> which of its points you are addressing here.

Sorry, I posted reply to the wrong post.

-- 
Dmitry Olshansky