-
Notifications
You must be signed in to change notification settings - Fork 4.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
Making Declaration of T* where T : struct Possible #3210
Comments
A struct isn't necessarily blittable or of a predictable size. If the struct contains a reference or native integer it will have different size at runtime. C# also doesn't specify a default pack leaving it up to the runtime. Both |
Some of the same concerns were covered in #126. |
Interesting. Would be nice if there were a way to signal that a struct is friendly to unsafe usage and then use that signal in generics for this kinds of issues listed above. |
I agree that generic pointers and @HaloFour: True, but the compiler knows these things at compile-time already. So it can always check whether the struct can be used in such a context. On the other hand, the runtime would also have to support this for reflection-based scenarios. I don't know if it does. Even if not, the compiler could simply generate the required code for each invocation with a specific type, similar to how C++'s templates work; F# does that too in certain cases. I'm not sure if that's a desirable approach however. |
The compiler is capable of figuring out this specific information if you're using a specific struct, yes. But when using generics it's not possible for the compiler to determine if generic type parameter is safe at compile time, let alone calculate the byte offsets that must be emitted directly into the IL of the generic method body. |
@HaloFour: Ah, now I see the problem. I originally assumed that the proposal added an additional generic constraint to indicate that |
@axel-habermaier, @HaloFour an added constraint would be ideal here. I'll happily update the suggestion. What would be a good name for the constraint? Perhaps something like |
@whoisj: I don't like |
You would need some kind of new constraint, as well as some mechanism in the CLR to actually care about and enforce that the struct is predictably blittable. But that doesn't solve the issue of indexing where the generated IL for the method needs to know the exact byte offsets and there is no way that the compiler can know the size of any given generic struct at compile time. |
@axel-habermaier I honestly do not know if the CLR understand this concept specifically, though one would assume it would have to otherwise I could grab an unsafe pointer to a struct with managed types in it via IL. I like the |
It's only the C# compiler that attempts to enforce this. The CLR doesn't know and doesn't care. It will happily let you index into an arbitrary offset, even out of bounds or with unpredictable types. The verifier stops bothering attempting to ensure correctness as soon as you break out the pointers. |
@HaloFour: When would the exact byte offsets be required? You can't access any fields of the struct in a generic context. |
Running through some tests it actually looks like the compiler is willing to break out the |
Yay, that's fantastic and good to know when I'm pushing for performance. 🎈 Do wish the compiler wouldn't get in the way here. Once I've stated
"Arguable"? If the developer has explicitly said |
Hence, "arguable". Clearly the language designers didn't think that |
The problem with "unmanaged" is it requires marshalling and back again, otherwise I would. 😞 I do understand the implications, and reasoning. It's just unfortunate that I often find myself thinking: we'd be a lot more productive in C#, too bad it's slow for this kind of stuff. With more lax |
We are now taking language feature discussion on https://github.com/dotnet/csharplang for C# specific issues, https://github.com/dotnet/vblang for VB-specific features, and https://github.com/dotnet/csharplang for features that affect both languages. |
It should be possible to create unsafe pointers to generic types so long as said types are value types (ala
where T : struct
). I find myself today writting code like the following for every type of value type I want to support (and there are many)Meaning I have a dozen methods or more, when a single method should be sufficient. If
T*
where possible whenT : struct
I could construct the following method and reduce the amount of boilerplate in my code significantly.Support for
sizeof(T)
is #3208The text was updated successfully, but these errors were encountered: