Re: dip1000: why can't the addressee come into existence later?

2018-11-10 Thread Neia Neutuladh via Digitalmars-d-learn
On Sat, 10 Nov 2018 16:25:40 +, Stanislav Blinov wrote:
> Yep, you just over-simplified the first case.

It is too simple to clearly illustrate why the code is invalid, but not so 
simple that the compiler accepts that code.

> Consider:
> 
> int* p;
> {
>  int i;
>  p = 
> }
> *p = 42;

In that example, the scope for i ends before the scope for p ends. It's 
not at all surprising that that code is wrong. In the other examples I 
gave, both i and p go out of scope at the same time.

But there's a total ordering for when variables' lifetimes end, which is 
the key (and non-obvious) difference between the two.


Re: dip1000: why can't the addressee come into existence later?

2018-11-10 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 10 November 2018 at 06:56:29 UTC, Neia Neutuladh 
wrote:

The following code doesn't work with @safe -dip1000:

int* p;
int i;
p = 

i has a shorter lifetime than p, the compiler complains.

But this code does:

int i;
int* p;
p = 

The compiler does this even in the absence of scope guards and 
destructors because simple, obvious rules will be easier to 
understand and implement than nuanced ones, even if it makes 
you reorder declarations sometimes.


Is this right?


Yep, you just over-simplified the first case. Consider:

int* p;
{
int i;
p = 
}
*p = 42;

or even:

module thing;

int* global;

void foo() {
int i;
global = 
}

...much simpler to just go by the lifetime, instead of attempting 
to do a complex analysis. Because for the latter, it would then 
*need* to be deep to be of any use at all. Especially in a 
language that has static ifs:


// parameter is not scope, function is not pure, etc.
void nasty(int* p) { /* ... */ }

void main() {
int *p;
int i;
p = 
static if (someCondition) nasty(p);
}



Re: dip1000: why can't the addressee come into existence later?

2018-11-10 Thread Neia Neutuladh via Digitalmars-d-learn
On Sat, 10 Nov 2018 11:47:24 +, Nicholas Wilson wrote:
> On Saturday, 10 November 2018 at 06:56:29 UTC, Neia Neutuladh wrote:
>> Is this right?
> 
> Are you sure you added @safe to the second example?
> https://run.dlang.io/is/2RbOwK fails to compile.

Maybe take another look at the post you're replying to? I was saying that, 
if the compiler allowed one thing that looked safe to me, it would either 
require nuance (check for scope guards, destructors, and the like before 
saying something is un-@safe) or allow other code that is obviously 
invalid.


Re: dip1000: why can't the addressee come into existence later?

2018-11-10 Thread Nicholas Wilson via Digitalmars-d-learn
On Saturday, 10 November 2018 at 06:56:29 UTC, Neia Neutuladh 
wrote:

Is this right?


Are you sure you added @safe to the second example?
https://run.dlang.io/is/2RbOwK fails to compile.


dip1000: why can't the addressee come into existence later?

2018-11-09 Thread Neia Neutuladh via Digitalmars-d-learn
The following code doesn't work with @safe -dip1000:

int* p;
int i;
p = 

i has a shorter lifetime than p, the compiler complains.

But this code does:

int i;
int* p;
p = 

In both cases, p can't point to i before i exists, and p ceases to exist 
when i ceases to exist.

I believe this is because the first option would let me write:

struct Foo
{
  bool exists = true;
  ~this() { exists = false; }
  void doStuff() { assert(exists); }
}

Foo* p;
scope(exit) (*p).doStuff;
Foo f;
scope(exit) destroy(f);
p = 

And this will run into the assert when -dip1000 should ensure it can't.

The compiler does this even in the absence of scope guards and destructors 
because simple, obvious rules will be easier to understand and implement 
than nuanced ones, even if it makes you reorder declarations sometimes.

Is this right?