Jump to page: 1 2
Thread overview
Is this documented behaviour?
Jul 23, 2013
John Colvin
Jul 23, 2013
Adam D. Ruppe
Jul 23, 2013
John Colvin
Jul 23, 2013
Dicebot
Jul 23, 2013
John Colvin
Jul 24, 2013
monarch_dodra
Jul 24, 2013
John Colvin
Jul 24, 2013
Dicebot
Jul 24, 2013
John Colvin
Jul 23, 2013
Jonathan M Davis
Jul 24, 2013
John Colvin
July 23, 2013
void foo(ref int a)
{
	a = 5;
}

void main()
{
	int a = 0;
	int* aptr = &a;
	
	foo(*aptr);
	assert(a == 5);
	
	a = 0;
	
	int b = *aptr;
	foo(b);
	assert(b == 5);
	assert(a == 0);
}

The fact that adding an explicit temporary changes the semantics seems weird to me.
July 23, 2013
There's nothing weird there because int b is a new variable, so assigning to it would not affect a in any case.
July 23, 2013
On Tuesday, 23 July 2013 at 16:40:53 UTC, Adam D. Ruppe wrote:
> There's nothing weird there because int b is a new variable, so assigning to it would not affect a in any case.

Sorry, I should have been more clear. It's the first case that seems weird to me.
July 23, 2013
On Tuesday, 23 July 2013 at 17:03:52 UTC, John Colvin wrote:
> Sorry, I should have been more clear. It's the first case that seems weird to me.

Why? '*aptr' is 'a' pretty much by definition of pointer dereferencing.
July 23, 2013
On Tuesday, July 23, 2013 18:34:51 John Colvin wrote:
> void foo(ref int a)
> {
> a = 5;
> }
> 
> void main()
> {
> int a = 0;
> int* aptr = &a;
> 
> foo(*aptr);
> assert(a == 5);
> 
> a = 0;
> 
> int b = *aptr;
> foo(b);
> assert(b == 5);
> assert(a == 0);
> }
> 
> The fact that adding an explicit temporary changes the semantics seems weird to me.

There is no such thing as an "explicit temporary." You declared a new variable, and since int is a value type, of course any changes to that new variable had no effect on the int that was used to initialize it. And you can't use temporaries with ref parameters regardless.

- Jonathan M Davis
July 23, 2013
On Tuesday, 23 July 2013 at 17:06:37 UTC, Dicebot wrote:
> On Tuesday, 23 July 2013 at 17:03:52 UTC, John Colvin wrote:
>> Sorry, I should have been more clear. It's the first case that seems weird to me.
>
> Why? '*aptr' is 'a' pretty much by definition of pointer dereferencing.

To be honest, I wasn't expecting foo(*aptr) to compile at all, with a "taking address of temporary" error or similar.

It's clearly the right behaviour to allow it, but it took me by surprise at first.
July 24, 2013
On Tuesday, 23 July 2013 at 20:13:33 UTC, John Colvin wrote:
> On Tuesday, 23 July 2013 at 17:06:37 UTC, Dicebot wrote:
>> On Tuesday, 23 July 2013 at 17:03:52 UTC, John Colvin wrote:
>>> Sorry, I should have been more clear. It's the first case that seems weird to me.
>>
>> Why? '*aptr' is 'a' pretty much by definition of pointer dereferencing.
>
> To be honest, I wasn't expecting foo(*aptr) to compile at all, with a "taking address of temporary" error or similar.
>
> It's clearly the right behaviour to allow it, but it took me by surprise at first.

"Pass-by-Ref" is pretty much sugar for "pass-pointer-by-value".

Basically, if you can take the address of the argument, then passing it is fair game. It's because you can't take the address of a temporary that you can't pass a temporary by ref (unless you are Microsoft Visual Studio, then there's no problem at all apparently 0_o).

Of course, "*aptr" does not return a temporary, so passing that is fair game too.
July 24, 2013
On Tuesday, 23 July 2013 at 20:13:33 UTC, John Colvin wrote:
> To be honest, I wasn't expecting foo(*aptr) to compile at all, with a "taking address of temporary" error or similar.

But there are no temporaries here. You seem to mix concepts of "temporary" and "stack variable with deterministic lifetime". Taking address of a temporary is something like this:

int foo() { return 42; }
...
int* ptr = &(foo());
July 24, 2013
On Wednesday, 24 July 2013 at 14:52:53 UTC, monarch_dodra wrote:
> On Tuesday, 23 July 2013 at 20:13:33 UTC, John Colvin wrote:
>> On Tuesday, 23 July 2013 at 17:06:37 UTC, Dicebot wrote:
>>> On Tuesday, 23 July 2013 at 17:03:52 UTC, John Colvin wrote:
>>>> Sorry, I should have been more clear. It's the first case that seems weird to me.
>>>
>>> Why? '*aptr' is 'a' pretty much by definition of pointer dereferencing.
>>
>> To be honest, I wasn't expecting foo(*aptr) to compile at all, with a "taking address of temporary" error or similar.
>>
>> It's clearly the right behaviour to allow it, but it took me by surprise at first.
>
> "Pass-by-Ref" is pretty much sugar for "pass-pointer-by-value".
>
> Basically, if you can take the address of the argument, then passing it is fair game. It's because you can't take the address of a temporary that you can't pass a temporary by ref (unless you are Microsoft Visual Studio, then there's no problem at all apparently 0_o).
>
> Of course, "*aptr" does not return a temporary, so passing that is fair game too.

I'm actually amazed how many years I've had the wrong conception of pointers in my head.

Despite having written *ptr = val a million times, I was still imagining *ptr to  be an rvalue i.e. read-from-this-address-and-return-value. How on earth did I never make the connection?!
July 24, 2013
On Wednesday, 24 July 2013 at 15:03:33 UTC, Dicebot wrote:
> On Tuesday, 23 July 2013 at 20:13:33 UTC, John Colvin wrote:
>> To be honest, I wasn't expecting foo(*aptr) to compile at all, with a "taking address of temporary" error or similar.
>
> But there are no temporaries here. You seem to mix concepts of "temporary" and "stack variable with deterministic lifetime". Taking address of a temporary is something like this:
>
> int foo() { return 42; }
> ...
> int* ptr = &(foo());

nope, I get that. I was just confusing the basics of how pointers work *facepalm*
« First   ‹ Prev
1 2