Jump to page: 1 24  
Page
Thread overview
May 30

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

May 31
Looks good.

This is everything I have argued /needs/ to happen (although I'd prefer inferred instead).
May 30

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

How do you turn off safe by default? With a compiler switch? I know some folks think it's good to punish people for writing unsafe code, as became clear in the earlier discussions, but safe by default is of no benefit to me, and I don't want to have to clutter my code with a bunch of boilerplate for no reason.

May 30

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

>

All declarations (i.e. functions with no body) must have exactly one of the @safe/@trusted/@system annotations or the module that contains them will fail to compile

please no

May 30

On Thursday, 30 May 2024 at 19:41:26 UTC, bachmeier wrote:

>

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

How do you turn off safe by default?

@system:
May 31

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

>

If there is no body, the compiler cannot verify the @safety of the function and in those cases this DIP proposes that there will be no default. All declarations (i.e. functions with no body) must have exactly one of the @safe/@trusted/@system annotations

For extern(D), there will be a linker error if a protoype is @safe but the implementation is @system. For other linkage, that case would silently link with no error. That breaks the principle of being able to grep for @trusted to find an accidental safety violation. (Deliberate violation with pragma(mangle) is less serious as that is intentional and stands out more to a reviewer).

Module 1:

import core.stdc.stdio;
@system extern(C) void ext(int* p) { p++; printf("%d\n", *p); }

Module 2:

@safe extern(C) void ext(int* p);

void main() // implicitly @safe
{
    int i;
    ext(&i); // boom
}

@safe should mean mechanically checked for accidental memory-safety violations - that is a more useful definition. Allowing non-extern(D) linkage prototypes to be @safe breaks that principle and makes @safe prototypes a minefield.

>

This DIP makes no distinction between extern(D), extern(C), and extern(C++) functions. Although the latter two usually apply to functions written in C or C++ respectively, that is not necessarily the case

A non-extern(D) prototype can be @trusted, and its implementation in D can be @safe, so the implementation is mechanically checked.

May 31

On Friday, 31 May 2024 at 09:18:17 UTC, Nick Treleaven wrote:

>

Module 2:

@safe extern(C) void ext(int* p);

void main() // implicitly @safe
{
    int i;
    ext(&i); // boom
}

Sorry, that doesn't compile even with -dip1000. But this does:

    auto p = new int;
    ext(p); // boom
May 31
Nick Treleaven kirjoitti 31.5.2024 klo 12.18:
> @safe should mean mechanically checked for accidental memory-safety violations - that is a more useful definition. Allowing non-extern(D) linkage prototypes to be @safe breaks that principle and makes @safe prototypes a minefield.

I agree in principle, but note this is orthogonal to the DIP. D allows declaring external C functions as `@safe` right now. The DIP should not make it any worse, and it also doesn't prevent a separate proposal that would say that external non-D linked functions must be either `@trusted` or `@system`.
May 31

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

I was glad to see some compromise on this. I'm still not 100% behind it, but it is less objectionable than before, IMO.

In terms of qualms, here is an example of a module that contains a mix of code, some of which is bringing in compiler intrinsics that don't have function bodies and part of it is additional functions:
https://github.com/libmir/mir-core/blob/master/source/mir/math/common.d
Under this DIP, this would no longer compile, which is fine it isn't hard to fix. My problem is with your recommendation elsewhere on the thread to add @system: at the top. Since the module mixes the intrinsics and functions together, that alone is not sufficient. The templates then would become @system instead of having their attributes inferred.

One way forward is to move everything without a body into a separate module with @system: at the top and publicly import that here. That's ok, although it separates the documentation. The other option is to go function by function to add the @system to each function.

I think some people have proposed solutions to this issue in the past when this comes up. I think it can't hurt to give some more thought to any improvements that can be brought to bear before this is adopted.

You're still potentially in for a lot of code breakage that could keep a lot of people on the old edition for a while. Hopefully the edition approach is able to make ease this transition, although it's hard to ignore the risk of bifurcation.

May 31

On Thursday, 30 May 2024 at 18:35:36 UTC, Atila Neves wrote:

>

https://github.com/atilaneves/DIPs/blob/safe-by-default/safe-by-default.md

Destroy!

I agree completely that "having [@safe] be opt-in makes it hard to use in practice" and that "defaults matter". However, I think that implementing Universal Function Attribute Inference would be a better way to address the shortcomings of the current defaults.

In "Thoughts on Backward Compatibility", I tried to figure out why some breaking changes succeed and others fail. The conclusion I came to was that breaking changes are most successful when:

  1. Migration is easy, or
  2. The change serves a goal that has strong buy-in from users

While there is a vocal minority in the D community who strongly support @safe (a group in which I include myself), I do not believe that @safe has strong buy-in from D programmers as a whole. In other words, this proposal cannot satisfy condition (2). It follows that, if we would like it to succeed, it must satisfy condition (1).

Sadly, I do not think migration to -preview=safedefault will be particularly easy. By the DIP's own admission, it "will likely break a lot of code". Even if editions allow us to mix pre-migration and post-migration code in the same project, the burden of migrating to -preview=safedefault will likely hurt the adoption of new editions, and cause projects that would otherwise upgrade to get "stuck" in the @system-by-default edition.

(It is also conceivable that new projects started by D programmers who don't care about @safe will choose the old, @system-by-default edition specifically to avoid the hassle of adding explicit @system attributes to their code.)

Universal inference avoids these problems. In most cases, it requires zero manual intervention to migrate existing code (that is, it Just Works™). The only major obstacle it faces is build performance when using separate compilation, and this obstacle can be overcome with toolchain improvements.

Inference also solves the wrong-default problem for @nogc, nothrow, and pure, in addition to @safe, without the need for any additional -preview switches or migrations. Asking users to migrate from @system-by-default to @safe-by-default may be doable, but can we really ask them to do the same thing three more times for the other attributes?

« First   ‹ Prev
1 2 3 4