On Tuesday, 13 August 2024 at 20:24:17 UTC, Mike Shah wrote:
>On Tuesday, 13 August 2024 at 15:44:45 UTC, Quirin Schroll wrote:
>Best one yet:
extern(C) int f() @trusted("Implementation is marked @safe");
If I own the implementation, is this possible? Call to f() would be ambiguous (See below example).
I think I get your sentiment though :) The 'reason' provided could be totally bogus -- BUT it will at least stand out for folks aiming for 100% @safe code.
Providing some mechanism to users to indicate if @trusted is being used as a bridge between @safe and @system code (intended use), or if @trusted is merely being used a temporary fix until you refactor cycles later could be useful.
I suppose you could also add your own User Defined Attribute (UDA) to indicate the state of the functions "safeness" as well though (e.g. @trusted int f() @("safe_eventually");) -- but that doesn't seem very robust.
1 import std.stdio;
2
3 extern(C) int f() @trusted;
4
5 @safe int f(){
6 return 42;
7 }
8
9 void main(){
10 f();
11 }
safe.d(10): Error: `safe.f` called with argument types `()` matches both:
safe.d(3): `safe.f()`
and:
safe.d(5): `safe.f()`
Failed: ["/usr/bin/dmd", "-v", "-o-", "safe.d", "-I."]
--- x.d
import std.stdio;
extern(C) void f() @safe {
writeln("Hello World!");
}
--- y.d
extern(C) void f() @trusted;
void main()
{
f();
}
You can try it on run.dlang.io
Of course you can't overload extern(C)
functions in the same module, but you can have a prototype in one module and the implementation in another. Marking non-extern(D)
prototypes as @safe
should not be allowed and is frowned upon by me and others as the compiler has no safeguards against getting it wrong, i.e. having a @system
implementation. For extern(D)
, attributes are part of mangling, so if you're getting those wrong, at least the linker errors.