@trusted attribute should be replaced with @trusted blocks

Steven Schveighoffer schveiguy at gmail.com
Thu Jan 16 19:18:09 UTC 2020


On 1/16/20 1:08 PM, Joseph Rushton Wakeling wrote:
> On Thursday, 16 January 2020 at 15:45:46 UTC, Steven Schveighoffer wrote:
>> In fact, because of how the system works, @safe code is LESS likely to 
>> mean what you think.
> 
> I'm not quite sure I follow what you mean here, can you clarify/explain?

For example, I want a safe function that uses malloc to allocate, and 
free to deallocate. Perhaps that is just scratch space and it's just an 
implementation detail.

I want everything *else* in the function to be safe. So I have to mark 
the function @safe, not @trusted. Otherwise I don't get the compiler checks.

In this way, @safe cannot really be used as a marker of "don't need to 
manually verify" because it's the only way to turn on the mechanical 
checking.

So there is more incentive to mark code @safe than @trusted at the 
function level. I guess I should have worded it as, you are probably 
going to see safe prototypes that more often then not still need checking.

Same goes for template functions. How do you even know whether it can be 
safe or not? You can try it, but that doesn't mean there's no trusted 
blocks inside.

I just don't see the practicality or validity of worrying about @trusted 
functions more than @safe ones from a user perspective.

That being said, code out there is almost always too trusting when 
marking functions @trusted. They should be small and easily reviewable. 
The longer the function, the more chances for assumptions to sneak in.

>> There are still cases where you still have to review functions that 
>> are @safe which do not have inner functions that are trusted. These 
>> are cases where data that is usually accessible to safe functions can 
>> cause memory problems in conjunction with trusted functions. When you 
>> need to break the rules, it's very hard to contain where the rule 
>> breaking stops.
> 
> For example, in a class or struct implementation where a private 
> variable can be accessed by both @safe and @trusted methods ... ?

A recent example was a tagged union [1]. The tag is just an integer or 
boolean indicating which member of the union is valid. As long as the 
tag matches which actual element of the union is valid, you can use 
trusted functions to access the union member.

However, safe code is able to twiddle the tag without the compiler 
complaining. The trusted code is expecting the link between the union 
member that is valid and the tag. In other words, you can muck with the 
tag all day long in @safe land, even in a completely @safe function. But 
it may violates the assumptions that the @trusted functions make, making 
the other parts unsafe.

Therefore, you have to review the whole type, even the safe calls, to 
make sure none of them violates the invariant.

And this is why some folks (ag0aep6g) disagree that trusted functions 
can be valid in this situation -- they have to be valid for ALL inputs 
in ALL contexts, because the alternative is that you have to manually 
check @safe code. I can live with the idea that @safe code needs 
checking within context, as long as it helps me ensure that *most* of 
the stuff is right.

The other option is to somehow use the compiler to enforce the semantic, 
like marking the *data* @system. In other words you are telling the 
compiler "I know that it's normally safe to change this tag, but in this 
case, you can't, because it will mess things up elsewhere".

-Steve

[1] https://github.com/dlang/phobos/pull/7347


More information about the Digitalmars-d mailing list