-
Notifications
You must be signed in to change notification settings - Fork 1k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
[Proposal] Add sizeof(T) support for unmanaged constraint #1508
Comments
I think you will still have to use struct ValueStruct { bool b1,b2,b3,b4; }
Unsafe.SizeOf<ValueStruct>().Dump();
Marshal.SizeOf<ValueStruct>().Dump();
|
@dangi12012 @omariom - If you are marshaling a struct then you must use the Marshal.SizeOf - that is what it's intended for. However I agree that being able to get the physical size in managed memory might be useful for some situations (I have done this before and wrote utility code to determine this at runtime). However @dangi12012 your post is unclear because sizeof(T) does actually compile and work...
|
Thats right. I need the size of the struct inside Memory. I dont plan to marshal it for C++. With Span developers really get a powerful tool which can be used in a safe manner. sizeof(T) should work with unmanaged keyword because the struct size can be determined at compile time and is blittable (No reference Types).
|
Really? That code can be compiled without any error. Do you want this to be compilable without unsafe context? |
Yes. This should be compilable without the use of the unsafe context. Span works in a safe context, so sizeof(T) where T : unmanaged would speed up things AND is safe after all. |
For arbitrary struct T, the size will only be known at runtime. For example, consider IntPtr fields, auto layout, and CLR implementation-defined padding. (Or did you mean JIT compile time?)
IMHO, it should work without unsafe context. It should even work without the unmanaged constraint. I have never understood why |
Could we proceed with this and make |
@xoofx, I would recommend creating an individual issue requesting the change. |
@xoofx - An alternative is to write a method that dynamically generates a delegate from IL instructions. That IL delegate is an algorithm that creates an instance of T and then determines the difference between the instance's address and the address of its highest offset member field. It then adds the length of that field. This reliably determines the physical size of 'T' as its defined in the managed environment. By making this a static operation with some form of dictionary, the above is done once and thereafter the cached size (keyed on typeof(T)) is then instantly available with almost no overhead at runtime. I used this to great effect once. |
Will do
Hm, sorry, I'm not sure to follow. We have already sizeof at the IL level, we can expose it and we are already using it in C#. We are just asking to make this sizeof operator fully available in C# so that we don't have to rely on an external IL lib to "un-restrict" it. The sizeof operator is important at IL level because it boils down to a compile time constant (at JIT or AOT time), so not sure why we would go to a more complicated route with allocations, a dictionary, locking...etc (note that you could make it without a dictionary actually with a static readonly field), just to get an information that is straightforward to get, even today, but alas, not integrated by default in the language, so we have to rely on an external/IL compiled lib (like |
Well then implement it please. |
It would be nice if these worked:
|
@imxzjv, The first scenario can't work because The runtime will treat The latter can't work because fixed sized buffers are constrained to a limited set of primitive type and would require a new feature (such as the already championed proposal: #1314) to extend that to support any type and be useable in "safe" code (relying on the ref return fe as true to work and relying on explicitly declared structs for type layout and sizing to be correct). |
2- would work with a new constraint: 1- works for static readonly but can never ever work for const. This compiles fine and static readonly is the same as const as far as the jit is concerned.
If my proposal were implemented you could drop the unsafe. Since the struct is safe you can see how my proposal makes sense for T : unmanaged |
....and literally every single struct type made in all of .NET ever? Sure, it's illegal now, but having a |
@tannergooding Here is an example of where I think |
It would make my code nicer when passing An example from last week is https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerrawinputdevices where I need to pass |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
If I use the unmanaged constraint on a generic type parameter the underlying type cannot contain any reference type. Ergo the size is known.
Can we have support for this:
This would make Marshal and unsafe unnecessary for much Pinvoke Code. Which is a very good thing for speed.
The text was updated successfully, but these errors were encountered: