January 15, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 1/8/2020 9:57 PM, Manu wrote: >> This is routinely done in Phobos by making a tiny one line anonymous @trusted >> lambda and immediately calling it. The compiler will inline it. > Unacceptable and embarrassing. > The compiler does not inline it (appears to be subject to > optimisation), You have to use the -inline switch (for DMD), that's true. > and LDC/GDC implement different inlining rules where > the compilers internal heuristics are undesirably perturbed by this > 'pattern'. It's a one-expression lambda. Why wouldn't it inline? I use one liner functions all the time, expecting them to inline. It's pervasive in D. Of course, I always use -inline for release builds. |
January 15, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau | On 1/9/2020 10:47 AM, Johannes Pfau wrote: > I agree that the lambda thing is an ugly hack and proper trusted blocks > would be better. It's intended to be that way. Bad language design is where the simple, straightforward code is considered bad form, for example, in C++: void foo(int array[]) // bad, boo hiss #include <vector> void foo(std::vector<int> array); // good, you get a gold star Besides, most of the ugliness I've seen comes from excessively trying to reduce the number of characters. Making it a regular nested function with a name makes it nice. > However, I wonder how languages with such blocks deal > with problems such as these: > > @safe void someFunction() > { > int[4] data; > // Lot's of code > @trusted > { > data.ptr[3] = 42; > } > } > > Now someone changes data to int[2]: > > @safe void someFunction() > { > int[2] data; > // Lot's of code > @trusted > { > data.ptr[3] = 42; > } > } > > So by modifying @safe code only, you introduced a memory safety issue. > The interface of a @trusted function however is more strictly defined: > > @trusted function set(ref int[4] data) > { > data.ptr[3] = 42; > } > > It's not possible to break the set function in @safe code. You could > probably argue that the trusted block in someFunction should have covered > the int[2] data definition and that you can also write @trusted functions > which do not properly check / enforce their parameters and can be broken > from @safe code. Exactly right. Let's make it look nicer: @safe void someFunction() { int[4] data; // Lot's of code @trusted void set() { data.ptr[3] = 42; } set(); } > But still, it seems like applying trusted/safe at function level provides > stronger guarantees. It also makes it easier for both the compiler and user to reason about. The user doesn't need to bother wondering/worrying if the compiler will detect breaking the @trusted code by changing the @safe code. |
January 15, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 1/13/2020 12:37 PM, Steven Schveighoffer wrote: > How does the DIP affect interfaces and class virtual functions? Especially interfaces without marking will be a potential problem as there will be no errors on a @system interface stub which now is tagged with @safe but has no implementation to complain about. But an implementing class would fail to compile potentially (and might be in a separate project). This is a fundamental API difference that's not easy to account for. The DIP should address that process. Unmarked introducing functions (such as the ones in Object) will have to be marked as @system. Later on we can mark them @safe as a separate transition issue. > I noticed that even templated class member functions are currently @system unless tagged @safe (for good reason). So there's going to be a lot of code out there like this. Templated functions get their safety inferred if not explicitly marked. |
January 15, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 15.01.20 19:08, Walter Bright wrote: > On 1/9/2020 10:47 AM, Johannes Pfau wrote: >> I agree that the lambda thing is an ugly hack and proper trusted blocks >> would be better. > > It's intended to be that way. Bad language design is where the simple, straightforward code is considered bad form, for example, in C++: > > void foo(int array[]) // bad, boo hiss > > #include <vector> > void foo(std::vector<int> array); // good, you get a gold star > ... Or perhaps #include <vector> void foo(std::vector<int> const &array); > Besides, most of the ugliness I've seen comes from excessively trying to reduce the number of characters. Making it a regular nested function with a name makes it nice. > ... Maybe it looks nice. A @trusted nested function that depends on enclosing @safe code to ensure memory safety is however still not valid. > ... > > Let's make it look nicer: > > @safe void someFunction() > { > int[4] data; > // Lot's of code > > @trusted void set() { data.ptr[3] = 42; } > > set(); > } > > >> But still, it seems like applying trusted/safe at function level provides >> stronger guarantees. > > It also makes it easier for both the compiler and user to reason about. The user doesn't need to bother wondering/worrying if the compiler will detect breaking the @trusted code by changing the @safe code. It will not. The "nice" version is bad. |
January 15, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Wednesday, 15 January 2020 at 18:26:31 UTC, Walter Bright wrote: > [snip] >> I noticed that even templated class member functions are currently @system unless tagged @safe (for good reason). So there's going to be a lot of code out there like this. > > Templated functions get their safety inferred if not explicitly marked. Even for templated member functions? Running the code below causes an error. The way @safe flows through to nested scopes seems to override it. import std; @safe pure: struct Foo { void foo(T)() { int x; int* y = &x; } void bar() { } } void main() { debug { writeln(isSafe!(Foo.foo!int)); writeln(hasFunctionAttributes!(Foo.foo!int, "pure")); writeln(isSafe!(Foo.bar)); writeln(hasFunctionAttributes!(Foo.bar, "pure")); } } |
January 15, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 1/15/2020 10:46 AM, Timon Gehr wrote:
> It will not. The "nice" version is bad.
Yeah, I realized after I posted it that it should be `static` and pass `data` by ref.
|
January 15, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to jmh530 | On 1/15/2020 11:13 AM, jmh530 wrote:
>> Templated functions get their safety inferred if not explicitly marked.
>
> Even for templated member functions?
Hmm, I think you're right.
|
January 16, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 1/15/20 1:26 PM, Walter Bright wrote: > On 1/13/2020 12:37 PM, Steven Schveighoffer wrote: >> How does the DIP affect interfaces and class virtual functions? Especially interfaces without marking will be a potential problem as there will be no errors on a @system interface stub which now is tagged with @safe but has no implementation to complain about. But an implementing class would fail to compile potentially (and might be in a separate project). This is a fundamental API difference that's not easy to account for. The DIP should address that process. > > Unmarked introducing functions (such as the ones in Object) will have to be marked as @system. Later on we can mark them @safe as a separate transition issue. This needs at the very least a section of the DIP. I would recommend some kind of deprecation period where people are told to mark their abstract and interface functions @system or @safe (and might even be worth making it an error for a short time to nudge them even further). Otherwise, you will have projects that compile just fine, but silently change their API when the DIP becomes the default. >> I noticed that even templated class member functions are currently @system unless tagged @safe (for good reason). So there's going to be a lot of code out there like this. > > Templated functions get their safety inferred if not explicitly marked. Sorry, I could have worded this better. Member functions of templated classes (i.e. virtual functions) are not inferred like they are for structs: class C(T) { T foo() { return T.init; } } struct S(T) { T foo() { return T.init; } } void main() @safe { S!int s; assert(s.foo == 0); // OK, S.foo inferred @safe auto c = new C!int; assert(c.foo == 0); // error, cannot call @system function C.foo } -Steve |
January 17, 2020 Re: DIP 1028---Make @safe the Default---Community Review Round 1 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Thursday, 2 January 2020 at 09:47:48 UTC, Mike Parker wrote:
> All review-related feedback on and discussion of the DIP should occur in this thread. The review period will end at 11:59 PM ET on January 16, or when I make a post declaring it complete.
>
This round of review is now closed. Thanks to everyone who participated.
|
Copyright © 1999-2021 by the D Language Foundation