Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 23, 2013 Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | 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 Re: Is this documented behaviour? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | 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*
|
Copyright © 1999-2021 by the D Language Foundation