Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CallerMustBeUnsafe] type attribute #972

Open
srivatsn opened this issue May 10, 2016 · 2 comments
Open

[CallerMustBeUnsafe] type attribute #972

srivatsn opened this issue May 10, 2016 · 2 comments
Labels
Feature Request help wanted The issue is up-for-grabs, and can be claimed by commenting
Milestone

Comments

@srivatsn
Copy link
Contributor

Ported from dotnet/roslyn#8663


From https://github.com/dotnet/coreclr/issues/3143

To mark a function to be only be able to be called in an unsafe block.

It came up as an issue with having an IntPtr based api for Vector.Copy be equally could apply to something like a .ctor where you are passing an internal buffer to use (e.g. https://github.com/dotnet/coreclr/issues/3142)

Or risk of use of buffers with overlapped I/O tasks and dispose dotnet/corefx#5954 (comment)

To indicate that the caller is aware there are risks and to be careful. What I am suggesting is something where .ctor 2 is forced to be unsafe in the same way .ctor 3 is:

public BufferedThing(int bufferSize){}

[CallerMustBeUnsafe]
public BufferedThing(byte[] internalBuffer){}

public BufferedThing(byte* internalBuffer, int bufferLength){}

e.g.

var buffer0 = new BufferedThing(10); // fine

var buffer1 = new BufferedThing(new byte[10]); // compile error

unsafe {
    var buffer2 = new BufferedThing(new byte[10]); // fine
}

unsafe {
    var buffer = new byte[10];
    fixed (byte* pBuffer = &buffer[0]) {
        var buffer3 = new BufferedThing(pBuffer, 10); // fine
    }
}
@dasMulli
Copy link

As mentioned in https://github.com/dotnet/corefx/issues/42251#issuecomment-553310965, I don't think mixing language concepts (unsafe keyword) with API level concepts ("unsafe operations" / "unsafe API") is a very good idea.

My primary reason is that it is just asking users to change a setting in their project file and add an unsafe block. This doesn't necessarily make users think about how the API should be used (esp. when there is a StackOverflow answer telling developers how to work around the produced diagnostic).

Truth is there are classes of APIs that are more prone to produce runtime errors (some of which are unrecoverable) and more "safe" APIs. Denoting APIs with UnsafeXYZ or DangerousXYZ is probably a way that makes it more visible in the code base about what is actually a part that can go wrong instead of marking a method with unsafe and then not knowing which part of it is actually "dangerous".

Applied to the API mentioned in the above example, I'd suggest a BufferedThing.DangerousCreateFromInternalBufferArray(byte[]) signature to make a dangerous / unsafe operation visible to consumers and during code reviews.

@sharwell
Copy link
Member

I would rather focus energy on analyzers to help users correctly use these APIs. The attribute doesn't seem to add clarity to the code, but rather confuses concepts of pointers with other code and raises a bunch of questions about where the attribute should and should not be applied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request help wanted The issue is up-for-grabs, and can be claimed by commenting
Projects
Status: Language/design
Development

No branches or pull requests

4 participants