pointers, functions, and uniform call syntax

monarch_dodra monarchdodra at gmail.com
Thu Sep 6 00:39:32 PDT 2012


On Thursday, 6 September 2012 at 06:18:11 UTC, 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 variable exists, where it points to isn't so much 
> the case), so it would be the same as comparing it to this...
>
>   int getx(S* s)
>   in {assert(&s);} //always true, and always wrong.

That is absolutely not true at all. Behind the scenes, *passing* 
a ref is the same as passing a pointer, yes, but afterwards, they 
are different entities. If you request the address of the 
reference, it *will* give you the address of the referenced 
object. It is NOT the same as what you just wrote:

--------
import std.stdio;

struct S
{
     int i;
}

void foo(ref S s)
{
     writeln("address of s is: ", &s);
     assert(&s);
}

void main()
{
     S* p;
     foo(*p);
}
--------
address of s is: null
core.exception.AssertError at main(11): Assertion failure
--------

>  As I mentioned, it's wrong and is misleading. You'd have to 
> work around the system to get the check correct; and even then 
> if the compile decides to do something different you can only 
> have it implementation dependent.
>
>   int getx(ref S s)
>   in {
>     S *ptr = cast(S*) s;
>     assert(ptr);
>   }
>
>  I'm not even sure this would even work (it's undefined 
> afterall). I hope I never have to start adding such odd looking 
> checks, else I would throw out ref and use pointers instead; At 
> least with them the checks are straight-forward in comparison.

Again, a reference and a pointer are not the same thing. That 
cast is illegal.

--------
main.d(10): Error: e2ir: cannot cast s of type S to type S*
--------

But *this* is legal and good though:

--------
int getx(ref S s)
in {
   S *ptr = &s;
   assert(ptr);
}
--------
Although it is just transforming the initial 1-liner into a 
2-liner...


More information about the Digitalmars-d mailing list