Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 16, 2018 @safe by default | ||||
---|---|---|---|---|
| ||||
Hi folks, I know there were a lot of discussions on this topic, and it is understandable that due to historical reasons the D language is designed with C/C++ interop in mind, so it means that there is no @safe by default. However, I also see a lot of people who want this feature, and I personally think that it would be great to have it, because it would save a lot of time by marking all functions as @safe by default, if it needs to. It is also understandable that it's not possible to change this behavior today, because of compatibility. That's true and that's OK to be honest, nothing wrong with it. I'm still learning D, so please accept my apologies if I don't see the whole picture, and if the question is obvious in some way, but I'd like to ask: Is it possible to introduce a new parameter/flag to the compiler, to force all functions be @safe by default on a per-module basis? For example: ``` module mymodule; pragma(safe); class Foo { // Already marked as @safe by "pragma(safe)" void bar() { ... } } // @safe by default void fooBar() { ... } ``` The same could be done to @nogc and maybe other attributes. I know that probably I'm not the first guy who proposing that, but to be honest, I didn't find any fresh discussion about it, so just decided to ask here. Thanks! |
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Shtokolov | On Saturday, 16 June 2018 at 13:52:37 UTC, Jacob Shtokolov wrote:
> Is it possible to introduce a new parameter/flag to the compiler, to force all functions be @safe by default on a per-module basis?
>
> For example:
>
> ```
> module mymodule;
>
> pragma(safe);
We already have that, and with even shorter syntax:
```
module mymodule;
@safe:
[...]
```
:-)
|
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bastiaan Veelo | On Saturday, 16 June 2018 at 13:57:48 UTC, Bastiaan Veelo wrote:
> On Saturday, 16 June 2018 at 13:52:37 UTC, Jacob Shtokolov wrote:
>> Is it possible to introduce a new parameter/flag to the compiler, to force all functions be @safe by default on a per-module basis?
>>
>> For example:
>>
>> ```
>> module mymodule;
>>
>> pragma(safe);
>
> We already have that, and with even shorter syntax:
>
> ```
> module mymodule;
>
> @safe:
>
> [...]
> ```
>
> :-)
OMG! Didn't know that! xD
Thank you Bastiaan!
|
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Shtokolov | On Saturday, 16 June 2018 at 14:02:36 UTC, Jacob Shtokolov wrote: > On Saturday, 16 June 2018 at 13:57:48 UTC, Bastiaan Veelo wrote: >> On Saturday, 16 June 2018 at 13:52:37 UTC, Jacob Shtokolov wrote: >>> Is it possible to introduce a new parameter/flag to the compiler, to force all functions be @safe by default on a per-module basis? >>> >>> For example: >>> >>> ``` >>> module mymodule; >>> >>> pragma(safe); >> >> We already have that, and with even shorter syntax: >> >> ``` >> module mymodule; >> >> @safe: >> >> [...] >> ``` >> >> :-) > > OMG! Didn't know that! xD > > Thank you Bastiaan! You're welcome! It could have been better documented probably, because I was just looking for it and still cannot find it. I remember having seen it so I'm quite sure it is in there somewhere. At least it could have been in https://dlang.org/articles/safed.html. Here is one reference from the forum: https://forum.dlang.org/post/nj73gp$1q3k$1@digitalmars.com Ah, found it, at the very top of https://dlang.org/spec/attribute.html Yeah, it can be made more obvious. |
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Shtokolov | On Saturday, June 16, 2018 14:02:36 Jacob Shtokolov via Digitalmars-d wrote:
> On Saturday, 16 June 2018 at 13:57:48 UTC, Bastiaan Veelo wrote:
> > On Saturday, 16 June 2018 at 13:52:37 UTC, Jacob Shtokolov
> >
> > wrote:
> >> Is it possible to introduce a new parameter/flag to the compiler, to force all functions be @safe by default on a per-module basis?
> >>
> >> For example:
> >>
> >> ```
> >> module mymodule;
> >>
> >> pragma(safe);
> >
> > We already have that, and with even shorter syntax:
> >
> > ```
> > module mymodule;
> >
> > @safe:
> >
> > [...]
> > ```
> >
> > :-)
>
> OMG! Didn't know that! xD
>
> Thank you Bastiaan!
I would point out that in general, doing that with attributes is rather error-prone, because it's easy for folks reading the code to miss them, making it unclear that they're in effect, and because unfortunately most attributes cannot be reversed, mass-applying them like that can then cause problems down the line when you need the attribute to _not_ apply to a function.
That being said, @safe is pretty much the one with the least problems, because it's one of the ones that you can reverse by using @system or @trusted explicitly where needed. However, there is no way to turn attribute inferrence back on, so putting @safe at the top of a module that has templated functions where the @safeness really needs to be inferred based on the template arguments can be a problem (though it's not as big a problem as putting @trusted at the top of the module, since at least with @safe, it just means that you'd end up with templates that don't compile when they would have been inferred as @system, whereas with @trusted, you'd potentially be hiding memory-safety bugs).
So, while putting @safe at the top of the module may very well be your best choice, be aware that mass-applying attributes like that _can_ cause problems.
- Jonathan M Davis
|
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Shtokolov | On 6/16/18 10:02 AM, Jacob Shtokolov wrote:
> On Saturday, 16 June 2018 at 13:57:48 UTC, Bastiaan Veelo wrote:
>> On Saturday, 16 June 2018 at 13:52:37 UTC, Jacob Shtokolov wrote:
>>> Is it possible to introduce a new parameter/flag to the compiler, to force all functions be @safe by default on a per-module basis?
>>>
>>> For example:
>>>
>>> ```
>>> module mymodule;
>>>
>>> pragma(safe);
>>
>> We already have that, and with even shorter syntax:
>>
>> ```
>> module mymodule;
>>
>> @safe:
>>
>> [...]
>> ```
>>
>> :-)
>
> OMG! Didn't know that! xD
>
> Thank you Bastiaan!
I would just caution that this does not affect member functions, only module-level functions. You have to repeat the @safe: inside any structs or classes as well.
-Steve
|
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Saturday, 16 June 2018 at 18:47:10 UTC, Steven Schveighoffer wrote: > I would just caution that this does not affect member functions, only module-level functions. You have to repeat the @safe: inside any structs or classes as well. Just tried that and it works very well (throws compilation errors): https://gist.github.com/run-dlang/ba59bcca4464d875f95f975d13bebe88 It seems that it works even for member functions! But still not sure about anonymous functions and delegates. |
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Saturday, 16 June 2018 at 17:46:56 UTC, Jonathan M Davis wrote: > I would point out that in general, doing that with attributes is rather error-prone, because it's easy for folks reading the code to miss them, making it unclear that they're in effect, and because unfortunately most attributes cannot be reversed, mass-applying them like that can then cause problems down the line when you need the attribute to _not_ apply to a function. > > That being said, @safe is pretty much the one with the least problems, because it's one of the ones that you can reverse by using @system or @trusted explicitly where needed. However, there is no way to turn attribute inferrence back on, so putting @safe at the top of a module that has templated functions where the @safeness really needs to be inferred based on the template arguments can be a problem (though it's not as big a problem as putting @trusted at the top of the module, since at least with @safe, it just means that you'd end up with templates that don't compile when they would have been inferred as @system, whereas with @trusted, you'd potentially be hiding memory-safety bugs). > > So, while putting @safe at the top of the module may very well be your best choice, be aware that mass-applying attributes like that _can_ cause problems. > > - Jonathan M Davis Thanks Jonathan! The case with templated functions indeed is not obvious. > doing that with attributes is rather error-prone, because it's easy for folks reading the code to miss them, making it unclear that they're in effect, and because unfortunately most attributes cannot be reversed, mass-applying them like that can then cause problems down the line when you need the attribute to _not_ apply to a function. I completely agree with the second point - if we can't reverse these attributes in random places, the feature doesn't make sense at all. The first point, however, looks arguable to me. So I would say that it strongly depends on the task: for example, in web development there is absolutely no need to use pointers and other unsafe features until you really need them. In this case it's better to force safety for all functions by default, and it would be hard to do if we need to mark every single function as @safe (not that hard of course, but very unpleasant). |
June 16, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Shtokolov | On Saturday, June 16, 2018 21:08:27 Jacob Shtokolov via Digitalmars-d wrote:
> On Saturday, 16 June 2018 at 17:46:56 UTC, Jonathan M Davis wrote:
> > doing that with attributes is rather error-prone, because it's easy for folks reading the code to miss them, making it unclear that they're in effect, and because unfortunately most attributes cannot be reversed, mass-applying them like that can then cause problems down the line when you need the attribute to _not_ apply to a function.
>
> I completely agree with the second point - if we can't reverse these attributes in random places, the feature doesn't make sense at all.
>
> The first point, however, looks arguable to me. So I would say that it strongly depends on the task: for example, in web development there is absolutely no need to use pointers and other unsafe features until you really need them. In this case it's better to force safety for all functions by default, and it would be hard to do if we need to mark every single function as @safe (not that hard of course, but very unpleasant).
The problem isn't whether changing the default is desirable. It's the fact that it's not at all obvious to anyone reading the code that that's what's happening - especially when you're dealing with stuff like github pull requests, where you're looking at a diff of the code and don't see the top of the file as part of the diff. This problem has popped up several times in druntime and Phobos where an attribute was mass-applied to a module or a struct, and it's caused varying levels of problems. Sometimes, it just means that an attribute ends up being applied locally in addition to being mass-applied, but in other cases, it's resulted in folks outright misunderstanding an aspect of the code that relates to the attribute that was mass-applied.
Personally, I think that it's just plain bad practice to mass-apply attributes precisely because it causes confusion about the code. And I'd say the same even if all attributes were reversible. Being able to do something like pure(false) would definitely be useful with mass-applied attributes, but it wouldn't fix the maintenance problems that come from applying attributes in a completely different part of the file from the function being affected.
So, while you're certainly free to mass-apply @safe (or any other attribute) if you think that that will improve your code, I'd advise against it.
- Jonathan M Davis
|
June 17, 2018 Re: @safe by default | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Shtokolov | On 6/16/18 4:27 PM, Jacob Shtokolov wrote:
> On Saturday, 16 June 2018 at 18:47:10 UTC, Steven Schveighoffer wrote:
>> I would just caution that this does not affect member functions, only module-level functions. You have to repeat the @safe: inside any structs or classes as well.
>
> Just tried that and it works very well (throws compilation errors): https://gist.github.com/run-dlang/ba59bcca4464d875f95f975d13bebe88
>
> It seems that it works even for member functions! But still not sure about anonymous functions and delegates.
Hm... interesting!
I guess for @safe it works, but other attributes (nothrow, pure), it doesn't. I assumed all the attributes behaved the same, but apparently not.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation