-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Unintuitive value type field access in .NET Core 3.1 vs .NET 5 #57712
Comments
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsWhile doing work to implement a If the contents of using System;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
unsafe class Program
{
struct A
{
public delegate* managed<void> First;
}
struct B
{
public A Inst;
public delegate* managed<void> Second;
}
static void One()
{
Console.WriteLine(nameof(One));
}
static void Two()
{
Console.WriteLine(nameof(Two));
}
static B* Alloc()
{
IntPtr* b = (IntPtr*)Marshal.AllocCoTaskMem(sizeof(B));
b[0] = (IntPtr)(delegate* managed<void>)&One;
b[1] = (IntPtr)(delegate* managed<void>)&Two;
return (B*)b;
}
static void Main()
{
B* b = Alloc();
// .NET Core 3.1 outputs "One"
// .NET 5 outputs "Two"
b->Second();
}
}
} /cc @RussKie @jkoritzinsky @elinor-fung
|
I think this is probably related to how function pointers types weren’t considered blittable until after 3.1, so the managed layout might not be sequential. #37295 |
@jkoritzinsky Good call. I think you're right. |
Have confirmed that converting the function pointers to |
Fix was already considered in dotnet/coreclr#28046 and rejected. |
While doing work to implement a
ComWrappers
solution it was discovered there is a discrepancy between .NET Core 3.1 and .NET 5. The .NET 5 behavior is what is expected. Consider the following code example which is similar to how one would construct a COM vtable. When run on .NET 5, the output is the expected "Two", but when running on .NET Core 3.1 the output is "One". This happens in both Debug and Release on .NET Core 3.1.If the contents of
A
are inlined intoB
the output is the expected "One".The disassembly for the calls:
.NET Core 3.1
.NET 5
/cc @RussKie @jkoritzinsky @elinor-fung
The text was updated successfully, but these errors were encountered: