Jump to page: 1 25  
Page
Thread overview
Shouldn't invalid references like this fail at compile time?
Jan 22, 2018
Aedt
Jan 23, 2018
Mike Franklin
Jan 23, 2018
Seb
Jan 23, 2018
ag0aep6g
Jan 23, 2018
Mike Franklin
Jan 23, 2018
Mike Franklin
Jan 23, 2018
Mike Franklin
Jan 23, 2018
Mike Franklin
Jan 23, 2018
Mike Franklin
Jan 23, 2018
ag0aep6g
Jan 23, 2018
Nicholas Wilson
Jan 23, 2018
Mike Franklin
Jan 24, 2018
Mike Franklin
Jan 24, 2018
Mike Franklin
Jan 24, 2018
Walter Bright
Jan 24, 2018
Mike Franklin
Jan 24, 2018
Jonathan M Davis
Jan 25, 2018
Walter Bright
Jan 25, 2018
Jonathan M Davis
Jan 24, 2018
lobo
Jan 24, 2018
Mike Franklin
Jan 24, 2018
lobo
Jan 24, 2018
Kagamin
Jan 26, 2018
Mike Franklin
Jan 26, 2018
H. S. Teoh
Jan 26, 2018
Jonathan M Davis
Jan 26, 2018
H. S. Teoh
Jan 24, 2018
Seb
Jan 24, 2018
Jonathan M Davis
Jan 25, 2018
Walter Bright
Jan 25, 2018
Mike Franklin
Jan 25, 2018
Mike Franklin
Jan 25, 2018
Walter Bright
Jan 25, 2018
Mike Franklin
Jan 25, 2018
Mike Franklin
Jan 25, 2018
Mike Franklin
Jan 25, 2018
Walter Bright
Jan 23, 2018
Kagamin
January 22, 2018
I was asked in Reddit (https://www.reddit.com/r/learnprogramming/comments/7ru82l/i_was_thinking_of_using_d_haxe_or_another/) how would D handle the following similar D code. I'm surprised that both dmd and ldc provides no warnings even with -w argument passed.

import std.stdio;

void main()
{
	string foo = "foo";
	string* p1, p2;
	
	string*[] ls;
	ls ~= &foo;
	p1 = ls[0];
	ls.destroy();
	p2 = ls[0];
	writeln(p2);

}
January 23, 2018
On Monday, 22 January 2018 at 23:30:16 UTC, Aedt wrote:
> I was asked in Reddit (https://www.reddit.com/r/learnprogramming/comments/7ru82l/i_was_thinking_of_using_d_haxe_or_another/) how would D handle the following similar D code. I'm surprised that both dmd and ldc provides no warnings even with -w argument passed.
>
> import std.stdio;
>
> void main()
> {
> 	string foo = "foo";
> 	string* p1, p2;
> 	
> 	string*[] ls;
> 	ls ~= &foo;
> 	p1 = ls[0];
> 	ls.destroy();
> 	p2 = ls[0];
> 	writeln(p2);
>
> }

D is not memory safe by default (unfortunately), so it's not surprising to me that you can do this in `@system` code.  I would be surprised if the compiler allowed you to do something like this in `@safe` code.  To make your programs memory safe, you should add `@safe` to your `main` function.

Mike


January 23, 2018
On Tuesday, 23 January 2018 at 00:20:45 UTC, Mike Franklin wrote:
> On Monday, 22 January 2018 at 23:30:16 UTC, Aedt wrote:
>> [...]
>
> D is not memory safe by default (unfortunately), so it's not surprising to me that you can do this in `@system` code.  I would be surprised if the compiler allowed you to do something like this in `@safe` code.  To make your programs memory safe, you should add `@safe` to your `main` function.
>
> Mike

Yep, DMD will complain:

https://run.dlang.io/is/x0Xfx8
January 23, 2018
On 01/23/2018 01:20 AM, Mike Franklin wrote:
> I would be surprised if the compiler allowed you to do something like this in `@safe` code.

You might get surprised then, if you expect the compiler to reject code like that statically.

If you add `@safe`, the compiler rejects this line:

    ls ~= &foo;

But that line would only be problematic if the pointer would leave the scope of the function. It doesn't, so this is actually safe. But the compiler isn't smart enough to see this.

The real question is about this line:

    p2 = ls[0];

That's an out-of-bounds access, and the compiler does not catch this statically. Instead, it inserts bounds-checking code that crashes the program safely with an `Error`.
January 23, 2018
On Tuesday, 23 January 2018 at 01:08:19 UTC, ag0aep6g wrote:

> If you add `@safe`, the compiler rejects this line:
>
>     ls ~= &foo;
>
> But that line would only be problematic if the pointer would leave the scope of the function. It doesn't, so this is actually safe. But the compiler isn't smart enough to see this.

https://issues.dlang.org/show_bug.cgi?id=18281



January 23, 2018
On Tuesday, 23 January 2018 at 01:08:19 UTC, ag0aep6g wrote:

> The real question is about this line:
>
>     p2 = ls[0];
>
> That's an out-of-bounds access, and the compiler does not catch this statically. Instead, it inserts bounds-checking code that crashes the program safely with an `Error`.

In trying to work out a solution to that, I ran across this oddity:

https://issues.dlang.org/show_bug.cgi?id=18282

January 23, 2018
On Tuesday, 23 January 2018 at 01:08:19 UTC, ag0aep6g wrote:

>
> The real question is about this line:
>
>     p2 = ls[0];
>
> That's an out-of-bounds access, and the compiler does not catch this statically. Instead, it inserts bounds-checking code that crashes the program safely with an `Error`.

Due to the aforementioned bugs in my prior posts, I couldn't even make an example to demonstrate in @safe code, so I modified the example slightly in an effort to reproduce the same problem.

import std.stdio;

void main() @safe
{
    string foo = "foo";
    string* ls0;
    string* p1, p2;

    ls0 = &foo;
    p1 = ls0;
    ls0.destroy();
    p2 = ls0;
    writeln(p2.length);
}

Error: program killed by signal 11

https://run.dlang.io/is/ecYAKZ

Yeah, that's pretty poopy.

Not sure how to precisely define the problem here.  Should `destroy` be `@system` so it can't be called in `@safe` code, or should the compiler be smart enough to figure out the flow control and throw an error?

Mike


January 23, 2018
On Tuesday, 23 January 2018 at 02:25:57 UTC, Mike Franklin wrote:

> Due to the aforementioned bugs in my prior posts, I couldn't even make an example to demonstrate in @safe code, so I modified the example slightly in an effort to reproduce the same problem.
>
> import std.stdio;
>
> void main() @safe
> {
>     string foo = "foo";
>     string* ls0;
>     string* p1, p2;
>
>     ls0 = &foo;
>     p1 = ls0;
>     ls0.destroy();
>     p2 = ls0;
>     writeln(p2.length);
> }
>
> Error: program killed by signal 11
>
> https://run.dlang.io/is/ecYAKZ
>

Gah!!! I screwed up that example, and I can't edit the post.  See the example here:

import std.stdio;

void main() @safe
{
    string foo = "foo";
    string* ls0;
    string* p1, p2;

    ls0 = &foo;
    p1 = ls0;
    ls0.destroy();
    p2 = ls0;
    writeln(p2.length);
}

Compile with `-dip1000`

Error: program killed by signal 11

https://run.dlang.io/is/6L6zcH

So that's bad.  But it looks like a bug in `-dip1000`, because if I compile without `-dip1000`, I get:

onlineapp.d(9): Error: cannot take address of local foo in @safe function main

https://run.dlang.io/is/rHpuf1

Mike


January 23, 2018
On Tuesday, 23 January 2018 at 02:38:42 UTC, Mike Franklin wrote:

> So that's bad.  But it looks like a bug in `-dip1000`

https://issues.dlang.org/show_bug.cgi?id=18283

January 23, 2018
On Tuesday, 23 January 2018 at 02:25:57 UTC, Mike Franklin wrote:
> Not sure how to precisely define the problem here.  Should `destroy` be `@system` so it can't be called in `@safe` code, or should the compiler be smart enough to figure out the flow control and throw an error?
>
> Mike

The compiler should be taught that any access to a `.destroy()`ed object is invalid i.e. that its lifetime ends when destroy is called.
« First   ‹ Prev
1 2 3 4 5