-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Champion: Unmanaged constructed types (16.3, Core 3) #1744
Comments
CC. @jaredpar, @jkotas, @davidwrighton |
Users can currently work around this using the |
This is less than ideal as well. Here is an example from our own CoreLib https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs#L286 :
My preference would be to allow taking address of any struct (generic and non-generic), and make taking address of managed structs produce on by default warning that one can suppress. It is fine for this to be a separate proposal if you would like. |
@jkotas, thanks for the suggestion. I do think this (allowing you to take the address of a "managed struct") would be better as a separate proposal. In the example you linked, it looks like it is going a step beyond even "allow taking the address of a managed struct" (which would be a struct containing a GC-tracked type) and is turning it into, effectively, "take the address of anything" (in the example, The current proposal mostly just requires relaxing an existing constraint in the compiler and some minor additional checking on |
That is left-over from times before we had ref locals. It should be a struct - other similar places in CoreLib are structs. I am fixing this in dotnet/coreclr#19193. I agree that "take the address of anything" would be hard to explain. "take the address of a managed struct" would be enough. |
Isn't it useful to mark the type as |
If you have a T that you want to take the address of sure. But, there a places (such as in the framework), where we cant use the unmanaged constraint (breaking change, etc) and where you still want to be able to take the address when it can statically be determined that a given struct is "unmanaged" and where we know it will always be unmanaged. |
I didn't mean the constraint. something like |
I mean, as @jkotas pointed out, there isn't anything at the IL level preventing it and you can get a pointer to such a struct with workarounds today (such as I think it might just be better to relax it entirely, but that probably requires more discussion and may be a slightly more controversial change... |
We could use this feature very nicely: We have some structs for p/invoke where the C side includes Being able to use generics could help us to avoid defining all the structs twice, which is more annyoing and error-prone than just using a Of course, having types for marshalling which map directly to the native C types would be even better... :-) - on the other hand, that might require CLR level changes, and for now, our code needs to support .NET Framework 4.6 in addition to the shiny new netstandard/netcore world... |
Not 100% sure if this already included, but for Unity it is very important that generic pointers inside structs will also be considered unmanaged. We would like to make sure the following code works:
|
@joeante that is fine by the spec. Pretty sure there is a test for that but if not @RikkiGibson can you add one? |
Yes. |
This can probably be closed in favour of #1937? |
Summary
Provide a way to take the address of a generic struct provided it does not contain any "managed" (GC-tracked) types.
For example, the following generic type is "unmanaged":
Motivation
Today, users have the ability to declare structs and take the address of it (in an unsafe context) provided that it is not considered a "managed" type.
However, there is nothing in the runtime preventing a user from taking the address of a generic struct and, in certain scenarios, it may be desirable to allow this.
One such example is the
System.Runtime.Intrinsics.Vector128<T>
type, which contains no GC tracked objects. The type is designed to be used in high-performance and generally unsafe scenarios, but there are certain operations (such asstackalloc
,pinning
, etc) which cannot be done in C# today.Design
The C# 6 spec states that an
unmanaged_type
is:This change would remove the restriction that
unmanaged_type
cannot be a constructed type. Instead, constructed types would be unmanaged if they meet the requirements of general user-defined struct types.Drawbacks
The compiler may need to do additional validation in order to validate that a user-defined generic struct is "ok" to use.
Notes
The user will still not be able to take the address of any type, which is possible to do in IL code today.
The text was updated successfully, but these errors were encountered: