On Thursday, 17 June 2021 at 10:28:42 UTC, Ola Fosheim Grøstad wrote:
>Indeed. But if you think about C functions that require arrays of zero terminated strings… Ok, you can create a simple @trusted wrapper, but then that wrapper has to check that all the strings are zero terminated, which adds unacceptable overhead. So even in this trivial example the @trusted code has to assume that the provided data structure is correct, and thus it enables @safe code to make correct @trusted code unsafe.
There are always trade offs. The best it is for trusted code to check the input arguments, and output too. We also have for this contract programming luckily. If you want performance, then it is really upon the owner of the project to decide. In worst case trusted at least marks pieces of code that need extra care during review and from testing point of view.
>It gets even more complicated in real system level programming where you might make a function @trusted because you know that when this function is called no other threads are running. That is an assumption about an invariant bound to time.
Proving things about timelines and concurrency is difficult/impossible. So, in practice, the correctness of @trusted is ad hoc, cannot be assumed to be local and requires audits as the code base changes.
Correct me if I'm wrong but this is also true for @safe functions, since safe is about memory mainly, not concurrency.
But it could be helpful to list the invariants unsafe code depends on, e.g.:
@unsafe(assumes_singlethreaded){
…fast update of shared datastructure…
}
@unsafe(pointer_packing, pointer_arithmetics){
…
}
@unsafe(innocent_compiler_workaround){
…
}
This may work if safety system offers safety not only for memory. I think you could rename unsafe to trusted, implying that underlying function is aware of the issue and resolves it at runtime somehow.
>Now you have something to scan for. Like, in testing you could inject a check before the code that assumes no threads to be running. If you build with GC then you can scan all used libraries that does tricks with pointers and so on.
The thing about trusted per my understanding is that it talks about inner code of the function itself, not behavior of the calling function. If you want safety, for input arguments, than call it from within a safe function.
For true system level programming something like this (or more advanced) is needed for people to use it. Otherwise just slapping @system on all the code is the easier option. There has to be some significant benefits if you want programmers to add visual noise to their codebase.
Well, it might be for true systems programming, but let's not forget that we have other use cases for D, such as GUI apps, web apps, console apps, and a plethora of other uses which might not necessarily, require every inch of performance to be squeezed, and more focus on convenience and better safety for lower cost of developing the product.
In summary, we do need to improve the @trusted functionality, and best to account for all use cases of D or at least to have a consistent and easy to use (not misuse) feature.
P.S. I really try to avoid use of trusted lambdas as much as possible, but sometimes I can't, and then I have the choice, either to use lambda, or slap entire function as trusted which I hate. And no extracting a two words unsafe operation into separate method, from a four word method, is not an appealing solution for me.