Replies: 3 comments 1 reply
-
cc: @AlekseyTs, others? |
Beta Was this translation helpful? Give feedback.
1 reply
-
I cannot say that I am sympathetic to all the concerns brought up here, especially those stated as strong as: "you are significantly breaking the functionality of type system and ABI." However, LDM decided to not go with the proposed syntax for now. |
Beta Was this translation helpful? Give feedback.
0 replies
-
Notes are now out, addressing many of these points: https://github.com/dotnet/csharplang/blob/main/meetings/2023/LDM-2023-05-01.md#fixed-size-buffers |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
The Problem
The proposal https://github.com/dotnet/csharplang/blob/main/proposals/inline-arrays.md uses an approach that lowers
int[4]
to a generatedBuffer4<int>
, but by using the tricky generatedBuffer4<int>
approach instead of introducing the realint[4]
type from IL, you are significantly breaking the functionality of type system and ABI.When developers expose a
int[4]
in an API, they expectint[4]
int[4]
to a parameter that has a compatible type, such asint[]
int[4]
without need of knowing what the actual lowered type is in advancetypeof(int[4]) == typeof(int[4])
which is the fundamental of a type system.Besides all above expectations cannot be meet, this proposal will also bring significant problems to the type system: the type I write is not the type I get.
Thinking about below two cases:
If we cannot use
typeof(int[4])
We now can use
typeof(int[])
to get theint[]
type, but we cannot usetypeof(int[4])
to get theint[4]
type, instead we can only usetypeof(Buffer4<int>)
to get a type that being lowered in the assembly that contains this type. Isn't it weird?Besides, if one
Buffer4<int>
from assembly A and anotherBuffer4<int>
from assembly B, willtypeof(A.Buffer4<int>) == typeof(B.Buffer4<int>)
returntrue
? Apparently it should because they are both the same typeint[4]
, but base on the implementation detailsA.Buffer4<int>
andB.Buffer4<int>
are actually two different types, so it shouldn't. How will you resolve this issue?If we can use
typeof(int[4])
Assuming we have below code in assembly A:
Now in assembly B we call the method
Foo
defined in the assembly A:Foo(typeof(int[4]))
returntrue
?Foo(B.Buffer4<int>)
returntrue
?This has the same issue with the previous case.
Despite the
typeof(int[4])
issueAssuming we have a method with signature
void FooA(int[4] buffer)
and a method with signaturevoid FooB(int[4] buffer)
defined in assembly A and B, respectively.Will
typeof(A.Program).GetMethod("FooA").GetParameters()[0].ParameterType == typeof(B.Program).GetMethod("FooB").GetParameters()[0].ParameterType
returntrue
? Apparently it should, but it can't because those twoint[4]
types are different.Conclusion and Solution
We can definitely allow developers to define their own safe buffer types using
InlineArray
, but we must not allow the typeT[const]
to be lowered to another generated struct that attributed withInlineArray
because once you allows it, you won't be able to fix this in future version of C# because tons of libraries will start to expose their safe buffer in public APIs, which will introduce significant problem to the type system.Alternatively we can make the lowered struct type internal so it won't be able to cross the boundary of assembly.
The best solution is to introduce support for safe fixed buffer type in IL directly, so it can be safely used across assemblies.
Beta Was this translation helpful? Give feedback.
All reactions