[Issue 21862] Taking address of non-static method without "this" should not be allowed

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon Dec 5 16:30:57 UTC 2022


https://issues.dlang.org/show_bug.cgi?id=21862

RazvanN <razvan.nitu1305 at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |razvan.nitu1305 at gmail.com
         Resolution|---                         |WONTFIX

--- Comment #1 from RazvanN <razvan.nitu1305 at gmail.com> ---
I have been looking into this and it seems that, surprisingly, this is intended
behavior. I first tried to fix it to give an error, but then realized that
actually this is correct code.

Right now, when we are talking about functions we have 2 categories: functions
or delegates. A function is represented by a function pointer, whereas a
delegate is represented by a function pointer and a context pointer.

When you take the address of a member function, as you are doing in the bug
report, the compiler simply sets the function pointer to the address of the
function code. However, member functions (unless they are static) also have a
context pointer that is passed behind the scenes as the first parameter. So in
the bug report code, we end up with code that looks like this:

int m(void* ctx, int x)
{ 
    return x;   // mov rax, rsi - returning second parameter
}   

void main()
{
    int function(int) func = &S.m;  // mov rax, m
    func(5)                      ;  // mov rdi, 5;
                                    // jmp rax
}

That's why we get garbage. You take the address of the function and then trick
the compiler to call m like it has a single parameter. Note that if the type of
func is delegate, then you correctly get 5, because now the compiler knows to
pass the ctx (null in this case) to m.

It is useful to be able to take the actual address of a function that is a
member function without requiring a context. The test suite is full of such
cases and if we disable this we are left with no alternative. On the flip side,
if main is marked as @safe, the code does not compile ("Error: `this` reference
necessary to take address of member `myFunc` in `@safe` function `main`").
Therefore, in safe code this is not allowed, but advanced users that understand
what happens may use this feature.

So this is actually an invalid bug report. Marking it as such, but please
reopen if I am missing something.

--


More information about the Digitalmars-d-bugs mailing list