Function pointers/delegates default args were stealth removed?

Manu turkeyman at gmail.com
Mon Aug 27 14:23:02 PDT 2012


On 28 August 2012 00:03, Walter Bright <newshound2 at digitalmars.com> wrote:

> On 8/27/2012 3:32 AM, Manu wrote:
>
>> Here's an advanced trick I use a lot since D doesn't extern to static C++
>> methods (heavily simplified, this is way out of context):
>>
>> struct CPPClass
>> {
>>      this()
>>      {
>>          // not my actual code, but effectively, write 'this' and the C++
>> method
>> pointer into a delegate on initialisation [I wrap this process up using
>> magic]
>>          void** pDelegate = cast(void**)&**cppNonVirtualMethod;
>>          pDelegate[0] = this;
>>          pDelegate[1] = pCPPMethodPointer;
>>      }
>>
>>      void delegate(int x = 0) cppNonVirtualMethod; // C++ methods often
>> have
>> default args
>>
>
>        void delegate(int x) cppNonVirtualMethod;
>        void callCppNonVirtualMethod(int x) { (*cppNonVirtualMethod)(x); }
>        void callCppNonVirtualMethod() { callCppNonVirtualMethod(0); }
>
> With inlining on, the calls to the second overload should disappear, and
> you have the same code generated as you would for the default arg method.
> You could probably reduce the typing with some sort of mixin template, but
> this is the basic idea.


I've actually considered this approach, and the overload isn't required in
this case, since the true method can have a default arg. The same pattern
can apply at the global scope.
There are 2 reasons I didn't go for it:

Every api call is a double-call with inlining turned off (debug builds).
Debug builds are already slow enough, I didn't want to base a design
decision on that when it was perfectly syntactically reasonable to call
through the function pointers directly.
__forceinline would address this concern. (I really need this anyway for
the simd api. simd intrinsics are all wrapped in templates; if these are
not inlined, making a function call for every math opcode, it's gonna be
waaaaay slower than using the fpu)

And the second is forward declarations and function definitiona appearing
within the same file (I have a feature request on this).
The API is easily defined by the function pointer, but since the definition
needs to define the default args, what now needs to be defined is a forward
declaration/prototype.
The trouble is, my module magic mixin can't produce the bodies for the
stubs it finds because a prototype and definition can't appear in the same
file.

void functionDecl(int x = 10); // declaration by user (ideally with an
custom attribute: @engine_import, which would inform the magic generating
mixin to produce a stub and linkage code for this)

// **** magically generated by a mixin: ****
void function(int) __functionDecl_ptr;
__forceinline void functionDecl(int x)
{
   __functionDecl_ptr(x);
}
// **************
static this()
{
  __functionDecl_ptr = importExtern("functionDecl");
}
// **************

Sadly, there's a lot missing from the language to be able to do that, but I
hope we can reach that place one day.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20120828/6f1f8bea/attachment.html>


More information about the Digitalmars-d mailing list