On 09/06/12 00:50, Era Scarecrow wrote:
> On Wednesday, 5 September 2012 at 11:01:50 UTC, Artur Skawina wrote:
>> On 09/04/12 20:19, Era Scarecrow wrote:
>>>  I ask you, how do you check if it's a null pointer? &s?
>>
>> Yes, obviously. If you need to do that manually.
> 
>  But you shouldn't have to.
> 
>>>   int getx(ref S s)
>>>   //How does this make sense?? it looks wrong and is misleading
>>>   in {assert(&s); }
>>>   body {return s.x); }
>>
>> It looks correct and is perfectly obvious. But see below - you don't need to 
>> do this manually - the compiler does it for you when calling methods and 
>> could handle the UFCS case too.
> 
>  How I'm understanding references in D (And perhaps I'm repeating myself in 
> two different topics) is they point to live variables (IE guaranteed 
> pointers), and remains this way until you return from that function. 

The struct example I gave previously (quoted below) shows how easily you can end
up with a null reference in D; refs are *not* guaranteed to be live. It's not
just about pointers:

   class C { int i; auto f() { return i; } }
   int main() {
      C c;
      return c.f();
   }

Here you won't even get an assert error, just a segfault. But the 
pointer-to-class
(reference type in general, but so far there are only classes) model chosen in 
D is
wrong; this probably contributes to the confusion about refs, because they 
behave
differently for classes. Let's ignore classes for now, they're "special".

>  This is entirely valid and simplifies things. Remember in D we want the 
> language to 'do the right thing', but if you make references where it works 
> to 'sometimes works' then it becomes a problem (pointers 'sometimes' work and 
> are not @safe, while ref is @safe). Checking the address of a reference 
> shouldn't be needed, since it should be dereferenced at where it was called 
> at if need be (throwing it there).

Pointers *are* @safe, it's just certain operations on them that are not.

>  Would you REALLY want to mark every single function that uses ref as 
> @trusted? 

No idea why you think that would be needed.

>>>  More importantly, if it's now a possibility do we have to start adding 
>>> checks everywhere?
>>>
>>>   int getx(S *s)
>>>   in {assert(s); } //perfectly acceptable check, we know it's a pointer
>>>   body {return s.x); }
> 
>>    struct S { int i; auto f() { return i; } }
>>    int main() {
>>       S* s;
>>       return s.f();
>>    }
>>
>> This program will assert at runtime (and (correctly) segfault in a 
>> release-build). The compiler inserts not-null-this checks for "normal" 
>> methods in non-release mode, and could also do that before invoking any UFCS 
>> "method". So you wouldn't need to check for '!!&this' yourself.
> 
>  I thought those checks weren't added (via the compiler) since if it causes a 
> seg fault the CPU would catch it and kill the program on it's own (just add 
> debugging flags); If you added the checks they would do the same thing (More 
> buck for the same bang).

The checks happen for structs, and should be configurable, but right now
are not, which sometimes causes trouble.


On 09/06/12 08:18, Era Scarecrow wrote:
> On Wednesday, 5 September 2012 at 11:01:50 UTC, Artur Skawina wrote:
>> On 09/04/12 20:19, Era Scarecrow wrote:
>>>  I ask you, how do you check if it's a null pointer? &s?
>>
>> Yes, obviously. If you need to do that manually.
>>
>>>   int getx(ref S s)
>>>   //How does this make sense?? it looks wrong and is misleading
>>>   in {assert(&s); }
>>>   body {return s.x); }
>>
>> It looks correct and is perfectly obvious. But see below - you don't need to 
>> do this manually - the compiler does it for you when calling methods and 
>> could handle the UFCS case too.
> 
>  I've been thinking about this; It would definitely be the wrong thing to do. 
> The assert would _Always_ succeed. The address you get would be of the 
> pointer/reference for the stack (the pointer 

No, that's not how ref args work. '&s' will give you the address of the
object (eg struct). A reference type like 'class' has another (internal)
level of indirection so in that case you would get a pointer to the
class-reference. But that's how classes work internally, the 'object' in
that case is just the  internal pointer to the "real" class data. Taking
the address of an argument gives you a pointer to it in every case.

artur

Reply via email to