Expose a concept of "unsafe callers only" #6304
Replies: 9 comments 15 replies
-
Could this be done as an analyzer instead? The case of having some attribute lead to errors/enforcement on other code seems like the poster child for analyzers. |
Beta Was this translation helpful? Give feedback.
-
CC. @stephentoub, @jkotas, @jaredpar, @GrabYourPitchforks This has been raised many times in the past and given that we are about to start considering .NET 8/C# 12 potential work items (and another discussion of this cropped up on Discord), I created a very basic rough draft of the topic and discussion points that have been raised. Whether we land on language changes, an analyzer, or something else, this does keep getting brought up release after release so it might be good to land on some decision and drive it forward (even if that is a decision that we do nothing and why). |
Beta Was this translation helpful? Give feedback.
-
Definitely a warning, the breaking potential of it is significant. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Actually there is, Actually I still use these attributes today because I compile my libraries even for .NET Framework; it's just they are completely ignored by the recent frameworks and analyzers. Instead of introducing new attributes for the same purpose wouldn't it be a good idea to make them meaningful again? So if you target also older platforms you don't need to unnecessarily duplicate the attributes. Disclaimer: I know that using |
Beta Was this translation helpful? Give feedback.
-
Related: we've also started compiling a preliminary list of "unsafe" APIs over at dotnet/runtime#41418. @EgorBo This also encompasses the |
Beta Was this translation helpful? Give feedback.
-
If I am using one of these functions in my function does the function that calls my function also has to be unsafe |
Beta Was this translation helpful? Give feedback.
-
Personally I feel like changing the meaning of |
Beta Was this translation helpful? Give feedback.
-
As someone who has to constantly explain that for example An analyser could probably do it, but I'd worry about whether IDEs would get their wires crossed by spotting a superfluous This would definitely be helpful as someone that regularly gets community members asking for help on how to avoid unsafe code, when they're using Silk.NET - a direct 1:1 binding library with no additional validation even in the cases you can use |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Unsafe Callers Only
Summary
C# should support the ability to annotate user-defined methods as
unsafe
such that they require callers to be in anunsafe { }
context. This could be achieved by a new attribute[UnsafeCallersOnly]
which preserves backwards compatibility or by taking a break to the language such thatunsafe means unsafe
.Motivation
There is no way for a user to declare a type or method and indicate to the caller that the API is considered
unsafe
without it also directly exposing a pointer like member. This often leads to an assumption that APIs which don't requireunsafe
are somehow safe or at least "safer" than the pointer taking equivalents. Likewise there are many APIs which areunsafe
which don't take pointers at all and there is currently no way to surface this information to the consumer.Providing a mechanism through which this information can be surfaced will result in higher visibility in code review and better surfacing of important information to the consumer.
Design
The non-breaking design is that we introduce a new attribute
[UnsafeCallersOnly]
(whose name mimics the[UnmanagedCallersOnly]
attribute used forunmanaged function pointers
). When this attribute is encountered on a type or member, the language will require that the caller likewise be marked[UnsafeCallersOnly]
or be calling the API from anunsafe { }
context. If the caller is not in anunsafe { }
context a diagnostic will be raised (it would be up to LDM to decide iferror
orwarning
was more appropriate).An alternative design that was suggested was that
unsafe should mean unsafe
. That is, theunsafe
modifier on a type or member would be equivalent to the proposed semantics of placing[UnsafeCallersOnly]
on the same. This would be a breaking change in that existing code would now surface errors on recompile using a new language version (and presumably emit something similar to[UnsafeCallersOnly]
at the IL level). However, it would match what many users I've talked to have indicated they thoughtunsafe
at this level meant.unsafe { }
within a member body would not convey the same, and so:The .NET Libraries would then be able to utilize this functionality on APIs such as
System.Runtime.CompilerServices.Unsafe
, System.Runtime.InteropServices.CollectionsMarshal,System.Runtime.InteropServices.MemoryMarshal
, andSystem.Runtime.InteropServices.Marshal
(subject to API review and approval).Open Questions
Is taking a breaking change worthwhile or is it better to preserve backwards compatibility and use an attribute instead?
Should this be surfaced as a warning or an error?
Could this be achieved using an analyzer rather than language support?
What would be the behavior in the case of
[UnsafeCallersOnly]
being placed on a member thatoverrides
a virtual?Beta Was this translation helpful? Give feedback.
All reactions