Skip to content
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

Getting address to a managed ref field returns the value of the field, not the address #68000

Closed
steveharter opened this issue Apr 27, 2023 · 3 comments
Labels
Area-Compilers Resolution-By Design The behavior reported in the issue matches the current design
Milestone

Comments

@steveharter
Copy link
Member

Version Used:
SDK 8.0.100-preview.3.23178.7
4.6.0-2.23177.13

Steps to Reproduce:
sharplab.io

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
internal ref struct Buffer
{
    public ref byte _f1;
    public int _f2;
}

public unsafe class C
{
    public static void M()
    {
        Buffer b;
        
        // This is null because 'ldfld' is used:
        IntPtr* p1 = (IntPtr*)&b._f1;
        // Also null:  (IntPtr*)Unsafe.AsPointer(ref b.f1;

        // This is not null because 'ldflda' is used:
        IntPtr* p2 = (IntPtr*)&b._f2;
    }
}

creates the relevant IL:

IL_0001: ldloca.s 0
> IL_0003: ldfld uint8& Buffer::_f1
IL_0008: conv.u
IL_0009: stloc.1
IL_000a: ldloca.s 0
IL_000c: ldflda int32 Buffer::_f2

Expected Behavior:
The pointer to the managed field _f1 to be non-null.

Actual Behavior:
The pointer to the managed field _f1 is null.

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Apr 27, 2023
@RikkiGibson
Copy link
Contributor

The language doesn't have a way of getting a ref to a ref variable. It makes sense to me that there also isn't a way to get a pointer to a ref variable.

I wonder if there's a pattern involving custom struct layouts and Unsafe.As which would permit getting that reference.

@steveharter
Copy link
Member Author

I wonder if there's a pattern involving custom struct layouts and Unsafe.As which would permit getting that reference.

Yes that is the case for my scenario. I need to get the offset of ref fields in a fixed layout ref struct, and ideally without doing ref arithmetic.

@jcouv
Copy link
Member

jcouv commented Apr 28, 2023

From discussion with @jarepar, this is expected and it mirrors the semantics with a ref parameter (see example below).
If we wanted to get a ref or pointer to the ref variable, we'd need some kind of new syntax (such as &(ref expr)).
I'll close this issue as by-design. Feel free to open a csharplang issue for language-level request (some new syntax).

Example (sharplab):

public class C 
{
    public  unsafe void M(int i, ref int j) 
    {
        var x = &i; // ldarga
        fixed (int* y = &j) { } // not ldarga
    }
}

@jcouv jcouv closed this as not planned Won't fix, can't repro, duplicate, stale Apr 28, 2023
@jcouv jcouv added Resolution-By Design The behavior reported in the issue matches the current design and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Apr 28, 2023
@jcouv jcouv added this to the 17.7 milestone Apr 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Resolution-By Design The behavior reported in the issue matches the current design
Projects
None yet
Development

No branches or pull requests

3 participants