Thread overview
templated lambda with {} cause GC
Aug 10, 2018
learnfirst1
Aug 10, 2018
rikki cattermole
Aug 10, 2018
Paul Backus
Aug 10, 2018
Simen Kjærås
Aug 10, 2018
learnfirst1
Aug 10, 2018
Paul Backus
August 10, 2018
import core.stdc.stdio;

struct Test {
	string name ;
}

void T(alias pred, A...)(){
	__gshared t = Test(A) ;
	 pred(t);
}

extern(C) void main(){
	T!(t => printf("test 1 name = %s\n".ptr, t.name.ptr), "test") ;  // build OK
	T!(t => {
		printf("test 2 name = %s\n".ptr, t.name.ptr);
	}, "test") ; // build error
}

--------------

build this with betterC

Undefined symbols for architecture x86_64:
  "__d_allocmemory", referenced from:
      __D4test4mainUZ__T9__lambda2TSQBb4TestZQvFNaNbNfQtZDFNbNiZv in test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: linker exited with status 1


to use without {}, it work as expect.

Is there a way to avoid this GC with {}, because we need multi line here.
August 10, 2018
On 10/08/2018 9:57 PM, learnfirst1 wrote:
> 
> import core.stdc.stdio;
> 
> struct Test {
>      string name ;
> }
> 
> void T(alias pred, A...)(){
>      __gshared t = Test(A) ;
>       pred(t);
> }
> 
> extern(C) void main(){
>      T!(t => printf("test 1 name = %s\n".ptr, t.name.ptr), "test") ; // build OK
>      T!(t => {
>          printf("test 2 name = %s\n".ptr, t.name.ptr);
>      }, "test") ; // build error
> }
> 
> --------------
> 
> build this with betterC
> 
> Undefined symbols for architecture x86_64:
>    "__d_allocmemory", referenced from:
>        __D4test4mainUZ__T9__lambda2TSQBb4TestZQvFNaNbNfQtZDFNbNiZv in test.o
> ld: symbol(s) not found for architecture x86_64
> clang: error: linker command failed with exit code 1 (use -v to see invocation)
> Error: linker exited with status 1
> 
> 
> to use without {}, it work as expect.
> 
> Is there a way to avoid this GC with {}, because we need multi line here.

Without the brackets it is inferring to not have state and hence is a function. But with the brackets it is assuming there is state required and hence has to allocate. Without manually allocating said state (not what you want), you cannot do this.
August 10, 2018
On Friday, 10 August 2018 at 09:57:53 UTC, learnfirst1 wrote:
>
> import core.stdc.stdio;
>
> struct Test {
> 	string name ;
> }
>
> void T(alias pred, A...)(){
> 	__gshared t = Test(A) ;
> 	 pred(t);
> }
>
> extern(C) void main(){
> 	T!(t => printf("test 1 name = %s\n".ptr, t.name.ptr), "test") ;  // build OK
> 	T!(t => {
> 		printf("test 2 name = %s\n".ptr, t.name.ptr);
> 	}, "test") ; // build error
> }
>
> --------------

The arrow syntax doesn't work for multi-line lambdas; you need to write them using what the spec calls "function literal" syntax [1]:

    T!((t) { // <- Parens around the argument, no arrow
        printf("test 2 name = %s\n".ptr, t.name.ptr);
    }, "test") ;

[1] https://dlang.org/spec/expression.html#function_literals
August 10, 2018
On Friday, 10 August 2018 at 09:57:53 UTC, learnfirst1 wrote:
> 	T!(t => {
> 		printf("test 2 name = %s\n".ptr, t.name.ptr);
> 	}, "test") ; // build error

This is not doing what you think it's doing. The syntax t => { return t; } is equivalent to t => () => t. That is, it's returning a function that takes no arguments, not a value.

For that very same reason, if you compile and run your code without -betterC, only the first printf() will be executed, and only one line of output will be generated.

What you should do instead is:
    T!((t){
            printf("test 2 name = %s\n".ptr, t.name.ptr);
        }, "test");

(note the lack of the => arrow)

--
  Simen

August 10, 2018
On Friday, 10 August 2018 at 10:38:53 UTC, Simen Kjærås wrote:
> What you should do instead is:
>     T!((t){
>             printf("test 2 name = %s\n".ptr, t.name.ptr);
>         }, "test");
>
> (note the lack of the => arrow)
>
> --
>   Simen


rikki cattermole , Paul Backus, Simen Kjærås: thanks for the explain, it work.


Still,  if my first example is use GC, why dmd not throw error at compile time, instead at link time report symbols is missing.   Is this a bug ?

August 10, 2018
On Friday, 10 August 2018 at 11:10:55 UTC, learnfirst1 wrote:
> Still,  if my first example is use GC, why dmd not throw error at compile time, instead at link time report symbols is missing.   Is this a bug ?

If you make your main function @nogc, you will get a compile-time error.