July 24, 2009
>>>          LOOKUP_TABLE[0] = Method("method1", &Component.method1);
>>>          LOOKUP_TABLE[1] = Method("method2", &Component.method2);
>>
>> These two lines are weird.  ``pragma(msg)`` shows that type of
>> ``&method1`` is ``void function()`` while it must be ``void delegate()``
>> for a non-static member because of difference in calling convention.
>> Actually I think that taking an address of a non-static member in a
>> static context must be a compile time error.
> 
> It's because I'm taking the address of the function on the type, not on an instance.  It's not a delegate because there's no "this" pointer yet.
> 
> It makes sense to me anyways.  A delegate is a normal function pointer coupled with a hidden context parameter.

But you can't call that function pointer. Actually, you can probably subvert type safety, because functions have a different calling conventions from delegates. This also means that SafeD should disallow taking the address of methods from a type (without instance).

That's really silly. A nicer way would be to make &Type.method return a delegate with ptr set to null. Then calling this delegate would result in a (harmless) null pointer exception.

But even then, there's no safe way to construct a real delegate out of the method pointer. You can't simply assign an object instance to ptr, because you can't statically know if the funcptr of the delegate really is a method of that object instance.

Looks like SafeD proves to be unfeasible again.
July 24, 2009
On Fri, 24 Jul 2009 09:56:41 -0400, grauzone <none@example.net> wrote:

>>>>          LOOKUP_TABLE[0] = Method("method1", &Component.method1);
>>>>          LOOKUP_TABLE[1] = Method("method2", &Component.method2);
>>>
>>> These two lines are weird.  ``pragma(msg)`` shows that type of
>>> ``&method1`` is ``void function()`` while it must be ``void delegate()``
>>> for a non-static member because of difference in calling convention.
>>> Actually I think that taking an address of a non-static member in a
>>> static context must be a compile time error.
>>  It's because I'm taking the address of the function on the type, not on an instance.  It's not a delegate because there's no "this" pointer yet.
>>  It makes sense to me anyways.  A delegate is a normal function pointer coupled with a hidden context parameter.
>
> But you can't call that function pointer. Actually, you can probably subvert type safety, because functions have a different calling conventions from delegates. This also means that SafeD should disallow taking the address of methods from a type (without instance).
>
> That's really silly. A nicer way would be to make &Type.method return a delegate with ptr set to null. Then calling this delegate would result in a (harmless) null pointer exception.
>
> But even then, there's no safe way to construct a real delegate out of the method pointer. You can't simply assign an object instance to ptr, because you can't statically know if the funcptr of the delegate really is a method of that object instance.

You mean no *compiler verifyable* safe way.  Of course there are provably safe ways to do it (my code is one of them).

> Looks like SafeD proves to be unfeasible again.

That's why there are system modules ;)  Note that a delegate's ptr method is a pointer, so you can't assign it/use it from SafeD anyways.

I'd propose a system module that defines an "unbound delegate" type.  This would be a function pointer coupled parameterized with a type, which has an opCall(T, ...) that would call the function properly.  I think it can be done, but I'm not enough of a template guru to do it myself.

That could be used in SafeD.

-Steve
July 24, 2009
Fri, 24 Jul 2009 09:07:30 -0400, Steven Schveighoffer wrote:

> On Thu, 23 Jul 2009 22:09:12 -0400, Sergey Gromov <snake.scaly@gmail.com> wrote:
> 
>> Thu, 23 Jul 2009 11:54:40 -0400, Steven Schveighoffer wrote:
>>
>>>          LOOKUP_TABLE[0] = Method("method1", &Component.method1);
>>>          LOOKUP_TABLE[1] = Method("method2", &Component.method2);
>>
>> These two lines are weird.  ``pragma(msg)`` shows that type of ``&method1`` is ``void function()`` while it must be ``void delegate()`` for a non-static member because of difference in calling convention. Actually I think that taking an address of a non-static member in a static context must be a compile time error.
> 
> It's because I'm taking the address of the function on the type, not on an instance.  It's not a delegate because there's no "this" pointer yet.
> 
> It makes sense to me anyways.  A delegate is a normal function pointer coupled with a hidden context parameter.

The ``Type.`` part does not change anything.  It simply directs compiler to use overloads from a particular class hierarchy level.   Here:

    static Method[] LOOKUP_TABLE2 = [
        { name : "method1", method : &Component.method1 },
        { name : "method2", method : &method2 }
    ];

This code compiled with DMD 1.046 gives the following errors:

    test2.d(30): Error: non-constant expression & method1
    test2.d(30): Error: non-constant expression & method2

Also if you add this code:

    pragma(msg, "outside: " ~ typeof(&method1).stringof);
    void method1() { writefln("method1");
        pragma(msg, "inmeth: " ~ typeof(&method1).stringof);
    }

you get:

    outside: void function()
    inmeth: void delegate()

So the type of a non-static method address taken in a static context is obviously wrong.
July 24, 2009
Fri, 24 Jul 2009 02:51:45 +0400, Sergey Gromov wrote:

> Thu, 23 Jul 2009 19:07:43 +0200, BLS wrote:
> 
>> Sergey Gromov wrote:
>>> Sorry, I'm not a guru at all, so ActiveX was a misnomer.  What I'm writing is a simple in-process server DLL which implements a couple of interfaces.
>> 
>> Oh, that's sad. :(
>> 
>> well, especially in this case I would suggest to have a look on this page : http://www.dsource.org/projects/juno/wiki/ComProgramming
> 
> Thanks, I'll look into it when I have time.

Juno is nice, and implements a lot of boilerplate.  But it doesn't seem to care enough about exceptions in user code.  My own code wraps every interface function in an exception catching block, and I'd better leave it that way.
1 2
Next ›   Last »