How does D allow delegates template options?

In the "Programming Language D" by Andrei Alexandrescu,

There is an example when a delegate is accepted as a template parameter:

T[] find(alias pred, T)(T[] input)
  if(is(typeof(pred(input[0])) == bool))
{
  for(; input.length > 0; input = input[1 .. $]) {
    if (pred(input[0])) break;
  }
  return input;
}

unittest {
  int[] a = [1,2,3,4,-5,3,-4];
  int z = -2;
  auto b = find!(delegate(x) { return x < z; })(a);
  asssert(b == a[4..$]);
}

Alexandrescu explains that this works because the delegate is actually a thick pointer that consists of two parts: a function pointer and a pointer to its stack stack (which is why z is available inside its body). Except that find accepts "pred" as a TEMPLATE parameter, not as an argument. And the template arguments can only be compile time constants.

I am sure that the address of the anonymous delegate in our unit test is indeed a compile-time constant, but the address of its stack frame, of course, should not be, therefore, as a delegate, the parameter can be selected as a template

What's going on here?

+4
1

, , .

:

0805c850 <_D6test564mainFZv20__T12__dgliteral1TiZ12__dgliteral1MFNbNfiZb>:
805c850:       55                      push   ebp
805c851:       8b ec                   mov    ebp,esp
805c853:       83 ec 04                sub    esp,0x4
805c856:       8b 48 d8                mov    ecx,DWORD PTR [eax-0x28]
805c859:       3b 4d 08                cmp    ecx,DWORD PTR [ebp+0x8]
805c85c:       0f 9f c0                setg   al
805c85f:       0f b6 c0                movzx  eax,al
805c862:       c9                      leave
805c863:       c2 04 00                ret    0x4

, ( btw). mov cmp .

, eax. , :

0805c868 <_D6test5632__T4findS18main12__dgliteral1TiZ4findMFNaNbNfAiZAi>:
 // snip a bunch of irrelevant code
805c870:       89 45 fc                mov    DWORD PTR [ebp-0x4],eax
// snip
805c892:       8b 45 fc                mov    eax,DWORD PTR [ebp-0x4]
805c895:       89 95 f8 ff ff ff       mov    DWORD PTR [ebp-0x8],edx
805c89b:       e8 b0 ff ff ff          call   805c850 <_D6test564mainFZv20__T12__dgliteral1TiZ12__dgliteral1MFNbNfiZb>

: -, : , dgliteral - !

-, , , eax, .

, _Dmain, find:

 805c7da:       89 e8                   mov    eax,ebp
 805c7dc:       e8 87 00 00 00          call   805c868 <_D6test5632__T4findS18main12__dgliteral1TiZ4findMFNaNbNfAiZAi>

! , , 0x28? _Dmain, :

 805c7d1:       c7 45 d8 fe ff ff ff    mov    DWORD PTR [ebp-0x28],0xfffffffe

, int z = -2; (-2 ​​ fffffffe 32 ). , .

, , , alias , , . , , , .

, , , , .

, dg - , . , , .

+7

Source: https://habr.com/ru/post/1531382/


All Articles