Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
August 10, 2018 templated lambda with {} cause GC | ||||
---|---|---|---|---|
| ||||
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 Re: templated lambda with {} cause GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to learnfirst1 | 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 Re: templated lambda with {} cause GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to learnfirst1 | 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 Re: templated lambda with {} cause GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to learnfirst1 | 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 Re: templated lambda with {} cause GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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 Re: templated lambda with {} cause GC | ||||
---|---|---|---|---|
| ||||
Posted in reply to learnfirst1 | 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.
|
Copyright © 1999-2021 by the D Language Foundation