Thread overview
Passing myself, a struct, as a C callback context
Mar 30, 2015
Paul O'Neil
Mar 30, 2015
weaselcat
Mar 30, 2015
Paul O'Neil
Mar 30, 2015
weaselcat
Mar 30, 2015
lobo
Mar 30, 2015
ketmar
Mar 30, 2015
Marc Schütz
Mar 31, 2015
Paul O'Neil
March 30, 2015
I'm registering a callback with some C code.  The simplified story is here, but the actual code is on GitHub [1] at the end if you care.

The call looks something like this.

void register(void(*fp)(void*), void* context);

I have a class that holds state for the callback and registers itself:

final class Klass
{
    void method()
    {
        register(callback_function, &this);
    }
}

As of dmd 2.067, doing "&this" is deprecated.  Is there an idiomatic way to do this?

[0] Actual code is at https://github.com/todayman/dubik/blob/master/source/vibe/core/drivers/rx.d#L177 .  The msg object eventually gets passed to the registration function.

Thanks,
-- 
Paul O'Neil
Github / IRC: todayman
March 30, 2015
On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:

> As of dmd 2.067, doing "&this" is deprecated.

where is this documented? I don't see it in the release notes.
March 30, 2015
On 03/29/2015 10:57 PM, weaselcat wrote:
> On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
> 
>> As of dmd 2.067, doing "&this" is deprecated.
> 
> where is this documented? I don't see it in the release notes.

I don't see it in the release notes either, but it's happening.  Maybe it's an instance of a more general thing?

-- 
Paul O'Neil
Github / IRC: todayman
March 30, 2015
On Monday, 30 March 2015 at 03:02:07 UTC, Paul O'Neil wrote:
> On 03/29/2015 10:57 PM, weaselcat wrote:
>> On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
>> 
>>> As of dmd 2.067, doing "&this" is deprecated.
>> 
>> where is this documented? I don't see it in the release notes.
>
> I don't see it in the release notes either, but it's happening.
>  Maybe
> it's an instance of a more general thing?

if it works in 2.066 you should submit a bug report, either this shouldn't be a deprecation or it should be in the release notes.
March 30, 2015
On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
> I'm registering a callback with some C code.  The simplified story is
> here, but the actual code is on GitHub [1] at the end if you care.
>
> The call looks something like this.
>
> void register(void(*fp)(void*), void* context);
>
> I have a class that holds state for the callback and registers itself:
>
> final class Klass
> {
>     void method()
>     {
>         register(callback_function, &this);
>     }
> }
>
> As of dmd 2.067, doing "&this" is deprecated.  Is there an idiomatic way
> to do this?
>
> [0] Actual code is at
> https://github.com/todayman/dubik/blob/master/source/vibe/core/drivers/rx.d#L177
> .  The msg object eventually gets passed to the registration function.
>
> Thanks,

This is only deprecated for class not struct. This code below works fine:

---
import std.stdio;

extern(C) void f2(void* ins) {
    auto s = cast(S*)(ins);
    writefln("f2():%s", s);
    writefln("f2():%s", *s);
}

void f1(void* ins) {
    auto s = cast(S*)(ins);
    writefln("f1():%s", s);
    writefln("f1():%s", *s);
}

struct S { // <<-- change to "class" to get deprecated message
    int value = 10;
    void f() {
        f1(&this);
        f2(&this);
    }

}

void main()
{
    auto s = S();
    s.f();
}
---

bye,
lobo
March 30, 2015
On Sun, 29 Mar 2015 22:53:35 -0400, Paul O'Neil wrote:

> I'm registering a callback with some C code.  The simplified story is here, but the actual code is on GitHub [1] at the end if you care.
> 
> The call looks something like this.
> 
> void register(void(*fp)(void*), void* context);
> 
> I have a class that holds state for the callback and registers itself:
> 
> final class Klass {
>     void method()
>     {
>         register(callback_function, &this);
>     }
> }
> 
> As of dmd 2.067, doing "&this" is deprecated.  Is there an idiomatic way to do this?
> 
> [0] Actual code is at https://github.com/todayman/dubik/blob/master/source/vibe/core/drivers/
rx.d#L177
> .  The msg object eventually gets passed to the registration function.
> 
> Thanks,

you still can cast `this` to void pointer: `cast(void*)this`

but beware of possible `opCast` overloads for `void*` (there are no in stdlib, but...)

March 30, 2015
On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
> I'm registering a callback with some C code.  The simplified story is
> here, but the actual code is on GitHub [1] at the end if you care.
>
> The call looks something like this.
>
> void register(void(*fp)(void*), void* context);
>
> I have a class that holds state for the callback and registers itself:
>
> final class Klass
> {
>     void method()
>     {
>         register(callback_function, &this);
>     }
> }

`this` is already a reference. You're taking the address of that reference. A  simple cast should work: `cast(void*) this`.
March 30, 2015
On 3/30/15 5:12 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Monday, 30 March 2015 at 02:53:36 UTC, Paul O'Neil wrote:
>> I'm registering a callback with some C code.  The simplified story is
>> here, but the actual code is on GitHub [1] at the end if you care.
>>
>> The call looks something like this.
>>
>> void register(void(*fp)(void*), void* context);
>>
>> I have a class that holds state for the callback and registers itself:
>>
>> final class Klass
>> {
>>     void method()
>>     {
>>         register(callback_function, &this);
>>     }
>> }
>
> `this` is already a reference. You're taking the address of that
> reference. A  simple cast should work: `cast(void*) this`.

To build on this further, &this for a class is actually taking a local stack reference, this is why it's not allowed.

And technically, cast(void*) this is dangerous in the general case because opCast can be overridden. If you absolutely need to get a pointer to a class reference, you would need to do this:

auto x = this;
auto p = &x;

For example, for a foolproof implementation of converting a class reference to void *, you would need to do:

auto x = this;
auto p = *(cast(void **)&x);

I wonder if those who made this change thought of this problem?

-Steve
March 31, 2015
On 03/30/2015 11:32 AM, Steven Schveighoffer wrote:
> On 3/30/15 5:12 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>>
>> `this` is already a reference. You're taking the address of that reference. A  simple cast should work: `cast(void*) this`.
> 
> To build on this further, &this for a class is actually taking a local stack reference, this is why it's not allowed.
> 
> And technically, cast(void*) this is dangerous in the general case because opCast can be overridden. If you absolutely need to get a pointer to a class reference, you would need to do this:
> 
> auto x = this;
> auto p = &x;
> 
> For example, for a foolproof implementation of converting a class reference to void *, you would need to do:
> 
> auto x = this;
> auto p = *(cast(void **)&x);
> 
> I wonder if those who made this change thought of this problem?
> 
> -Steve

Thanks for the explanation.  This makes a lot of sense - I forgot that "ref" actually means "special pointer."

Luckily, I don't plan on overriding opCast!

-- 
Paul O'Neil
Github / IRC: todayman