Thread overview | |||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 22, 2018 Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aedt | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: Shouldn't invalid references like this fail at compile time? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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.
|
Copyright © 1999-2021 by the D Language Foundation