March 26, 2020
On Thu, Mar 26, 2020 at 04:22:01PM -0600, Jonathan M Davis via Digitalmars-d wrote: [...]
> So, it should be fine to treat any and all function definitions as @safe by default, because the compiler can verify their @safety and provide the appropriate errors when the code isn't actually @safe. However, any function _declarations_ which are not extern(D) must not be treated as anything other than @system by default, or they introduce a hole into the @safety system.
[...]

Very good, I think this is the key point here.  If a function is *defined* (i.e., function body is visible to the compiler), then it doesn't matter whether it's extern(C) or not, it can be @safe by default because the compiler will check the function body and reject it if it breaks @safe.

Where the problem crops up is when it's an extern(C) *declaration* without a function body.  Then assuming @safe by default is essentially equivalent to declaring @trusted: at the top of the file, because who knows *what* that declaration will actually bind to at runtime.  You're essentially blindly trusting that the C code (or D code, but the compiler can't tell) behind it is actually @safe.  And worse than the programmer writing @trusted: at the top of the file, this is *implicit*, and the programmer may not even be aware that there's a problem.


T

-- 
There are four kinds of lies: lies, damn lies, and statistics.
March 26, 2020
On Thursday, March 26, 2020 8:24:24 AM MDT Adam D. Ruppe via Digitalmars-d wrote:
> On Thursday, 26 March 2020 at 14:12:24 UTC, Steven Schveighoffer
>
> wrote:
> > I still think this is the appropriate path. We cannot continue to ignore memory safety as a secondary concern just because C code is by-default unsafe. Memory unsafe HAS to be opt-in for any new modern language to succeed.
>
> What frustrates me about these discussions is the facts that slices always check bounds by default. The GC prevents use-after-free bugs by default.
>
> C doesn't do those. So assuming C's problems apply to D is fallacious. Rust's complication is because they wanted to avoid the runtime checks. But D's runtime checks are also a valid solution.
>
> I suspect 95+% of C's problems already are extremely rare in D, yet the @safe advocates never seem to consider this at all.

Except that in @system code, the bounds checking gets turned off with -release. So, with @system as the default, a lot less bounds checking is going on than I think many people realize.

Sure, D code is much less likely to have @safety issues than C code, but the @safety system is really designed with the idea that almost all code will be @safe with only pockets of it being @system or @trusted, and as long as a large percentage of code is @system, stuff like bounds checking or scope with DIP 1000 doesn't really do what it's supposed to.

- Jonathan M Davis



March 26, 2020
On Thursday, March 26, 2020 4:54:53 PM MDT rikki cattermole via Digitalmars- d wrote:
> And then there is .di files which complicates the matters further.
>
> But I agree with you.
>
> If the compiler _cannot_ or has _not_ confirmed it is @safe, a function should not be marked as @safe and be callable.

Actually, .di files don't complicate things much. non-extern(D) declarations have to be treated the same no matter where they are, and anything with a function body in a .di file is the same as if it were in a .d file. The only real difference is that you then have extern(D) declarations added into the mix, and because whether they're @safe, @trusted, or @system is part of their name mangling, they cannot link if they don't have the same @safety level as the corresponding function definition (which was verified by the compiler if it's @safe). So, the compiler can treat extern(D) function declarations as @safe by default just like it does function definitions without there being a problem. The only real issue is if the declaration and definition don't match, which is a problem regardless of what the default @safety level is.

- Jonathan M Davis



March 26, 2020
On Thursday, 26 March 2020 at 23:10:17 UTC, Jonathan M Davis wrote:
> Except that in @system code, the bounds checking gets turned off with -release.

This is one of the reasons why I tell people to NEVER use -release, it is plain awful and should be formally deprecated. The -boundscheck and -check switches fully replace it and are more obvious what they do.

But regardless, the right thing is still the default.

March 26, 2020
On Thursday, 26 March 2020 at 19:30:16 UTC, Steven Schveighoffer wrote:
> On 3/26/20 2:56 PM, Arine wrote:
>> On Thursday, 26 March 2020 at 15:02:15 UTC, Steven Schveighoffer wrote:
>>> Writing
>>>
>>> @system:
>>>
>>> At the top of your modules is not a big burden. If that drives you away from the language, then I'm sorry to say that you are missing out on the awesomeness of D, but I can't really help you.
>> 
>> I can, just write
>> 
>> @trusted:
>
> This isn't a good idea. But yeah, you can do that at your own peril (and anyone who uses your library). I'd highly recommend using @system: instead.

There are problems with @system:, they are outlined in great detail in the first review thread (just as @safe: has the same issues). I don't really feel like repeating the same arguments over and over again just to have someone tell me to just use @system: again. You can search the previous thread. @trusted: will be the only true easiest solution. If you are writing @system it really doesn't matter to you either way. Those that suffer are the people that care about @safe, just as it is the people using @system now that will suffer if this DIP goes through without any kind of proper backwards compatibility measure set in place (like any good language has).

>> This will be my goto solution as D lacks the means many other languages have to maintain compatibility.
>
> The means are: use the correct markings. @system works now, and will after this change.

They are correct for the *current* version of D. This DIP will break that. If I'm using a library and the author hasn't updated their library, it is now my burden to update their library as well. I have to maintain their library.

The problem isn't what works now. The problem is that there is going to be a change, that change is going to break code. That code will have to be updated to work after the change. There's no easy way to just have that code work again.

What you are basically telling people is that if they are using 10 different libraries, that they should take on the responsibility of maintaining those libraries and update them to be compatible with this change. This is not **practical**.

You know what Rust does? There's a version indicator in cargo config files that specifies what version of Rust to use.

Let's say Rust decided to change the default to be "unsafe" in the next version of Rust. If you created a new project and used a library that still required the old version of Rust. You can still build and use that library like normal. How is this such a foreign concept that people are willing to argue tooth and nail against having backwards compatibility instead of breaking a large amount of code because a default is being change (don't forget about @nothrow; this is why DIPs shouldn't be looked at on their own and why most other languages create different versions/standards).

>>> How many people were driven away from windows development because they had to deal with __stdcall? You just googled for it (or whatever the hell was available at the time), said "oh this is how you do it", and did it. It wasn't a problem, you just did it.
>> 
>> You don't need to do that anymore, they changed it (for the better). It probably did drive people away. Especially when you deal with small issues consistently. They start piling up, and you can only deal with so many tiny issues (which D has many of; and will only grow with all the new changes coming forward).
>
> Meh, you just do it. Saying "why do I have to write @system when I don't care about safety" is like saying "why do I have to write void when I have no return value". Just do it, and your code works. For those who don't care.

Why do I have to fix my code because of a change the compiler made with no easy solution to maintain backwards compatibility. Updating my code isn't an easy solution. That's the problem. Practicality is what is at stake. People don't have time to waste to keep their code simply compiling.

>>> This is only even a discussion because of the current situation. If D started out this way, you would have no idea there was even a problem here.
>> 
>> Right, because people don't want to have to keep updating their code or have it be broken. Other languages ensure backwards compatibility, and if they don't they provide a way to keep the code working without having to modify the code to work.
>
> I think the intention is to have an automated tool to mark things that are currently @system as @system explicitly. I would expect that feature in dfix, before this would become the default.
>
> You are free to use other languages if you feel that way. IMO this change is for the better, and provides a much healthier default. Without it, most code is @safe-but-not-marked as that is the default. The new default will allow more usage of @safe.

This isn't the only breaking change taking place. There are a large number of breaking changes happening. Yes this is only one DIP, and I'm sure someone will pop up saying "don't discuss other DIPs, this thread is only for DIPxxxx". That's the problem when there's only one "version" of D and DIPs are split apart without being able to look at the overall picture of what is happening.

I agree, it is probably for the better. The changes made in python 3 was for the better. Look at what they did for changes that were for the better. Did they break all code in existence? Or did they provide a means for people to keep their existing code working without a significant waste of resources to update it.

>> D's solution to the problem: "this is the best practice now". That doesn't stop already written code from being broken.
>
> Or again, switch to a "sensible" language like Rust or C# or C++. Don't pick Swift though, they change stuff all the time, it probably is going to die soon, I doubt anyone will put up with that.
>
> -Steve

The way Apple operates, I wouldn't doubt Swift being killed off :). I see Walter and Apple having a lot in common, except that one is actually successful.


March 26, 2020
On 3/26/20 7:31 PM, Arine wrote:
> There are problems with @system:, they are outlined in great detail in the first review thread (just as @safe: has the same issues)

They are not the same issues.

If you put @safe: at the top, you get no inference of templates, so those that could compile as @system code cannot compile now.

@system does indeed turn off inference, but there are less restrictions for @system. So more stuff can compile.

If you don't care, then just put @system: at the top. On the off chance that something needs to be @safe (like a lambda), mark it @trusted.

-Steve
March 27, 2020
On Wednesday, 25 March 2020 at 14:10:18 UTC, Steven Schveighoffer wrote:
> I would argue that if the compiler is going to make things @safe by default, then things that are not marked and are not @safe should not compile AT ALL COSTS. Otherwise the value of @safe is completely lost.

I don't think extern(C) should get special behavior.

- For code which can be machine-verified that it's @safe, the compiler should default to assuming they're @safe and ask the programmer to otherwise specify when it's not (@system or @trusted).

- For code which the compiler cannot verify whether it's safe, it should be assumed that it's @system.

This applies to extern(D) declarations, too. Effectively, this would mean that functions with a body won't need a @safe annotation, but functions without a body will require it. However, I think this is a more correct solution despite this issue.
March 27, 2020
On Friday, 27 March 2020 at 02:31:13 UTC, Vladimir Panteleev wrote:
> This applies to extern(D) declarations, too. Effectively, this would mean that functions with a body won't need a @safe annotation, but functions without a body will require it. However, I think this is a more correct solution despite this issue.

An afterthought. Because safety is part of D mangling, body-less extern(D) declarations could be assumed to be @safe. A mismatch (assumption of @safe but a @system implementation) will result in a linker error.

This applies to all mangling schemes which can represent @safe, which is only extern(D) at the moment. So, if any calling convention would be special in this regard, it would be extern(D).
March 27, 2020
On Friday, 27 March 2020 at 02:35:56 UTC, Vladimir Panteleev wrote:
> On Friday, 27 March 2020 at 02:31:13 UTC, Vladimir Panteleev wrote:
>> This applies to extern(D) declarations, too. Effectively, this would mean that functions with a body won't need a @safe annotation, but functions without a body will require it. However, I think this is a more correct solution despite this issue.
>
> An afterthought. Because safety is part of D mangling, body-less extern(D) declarations could be assumed to be @safe. A mismatch (assumption of @safe but a @system implementation) will result in a linker error.
>
> This applies to all mangling schemes which can represent @safe, which is only extern(D) at the moment. So, if any calling convention would be special in this regard, it would be extern(D).

Linker error are some of the most unfriendly way to do diagnostic.
Having all declarations without definitions needing to be explicitly annotated is IMO much better.
There aren't that many places out there where such a pattern is used anyway.
March 27, 2020
On Thursday, 26 March 2020 at 23:09:23 UTC, H. S. Teoh wrote:
> On Thu, Mar 26, 2020 at 04:22:01PM -0600, Jonathan M Davis via Digitalmars-d wrote: [...]
>> So, it should be fine to treat any and all function definitions as @safe by default, because the compiler can verify their @safety and provide the appropriate errors when the code isn't actually @safe. However, any function _declarations_ which are not extern(D) must not be treated as anything other than @system by default, or they introduce a hole into the @safety system.
> [...]
>
> Where the problem crops up is when it's an extern(C) *declaration* without a function body.  Then assuming @safe by default is essentially equivalent to declaring @trusted: at the top of the file, because who knows *what* that declaration will actually bind to at runtime.  You're essentially blindly trusting that the C code (or D code, but the compiler can't tell) behind it is actually @safe.  And worse than the programmer writing @trusted: at the top of the file, this is *implicit*, and the programmer may not even be aware that there's a problem.
>
>
> T

I strongly agree with this viewpoint.  Calling extern(C) code is like anything else @safe prohibits.  Yes, it *could* be safe, but the compiler should flag if @safe code potentially calls code written in a language that isn't memory safe, and the onus should be on the programmer to check the code and mark it appropriately.