www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - "is not an lvalue" when passing template function to spawn function

reply Bienlein <fm2002 web.de> writes:
Hello,

I get the error "`addToBiz(T)(Biz!T biz)` is not an lvalue and 
cannot be modified" when compiling the code below. Can't find a 
way how to do it right. Am a D newbie and would appreciate some 
help.

Thank you, Bienlein



class Biz(T) {

         private T value;

         this(T value) {
             this.value = value;	
         }

}

     static void addToBiz(T)(Biz!T biz)
     {
         // ...
     }


     int main()
     {
         auto biz = new Biz!int(123);
         spawn(&addToBiz, biz);
     }
Nov 08 2023
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 8 November 2023 at 16:30:49 UTC, Bienlein wrote:
 Hello,

 I get the error "`addToBiz(T)(Biz!T biz)` is not an lvalue and 
 cannot be modified" when compiling the code below. Can't find a 
 way how to do it right. Am a D newbie and would appreciate some 
 help.

 [...]

     static void addToBiz(T)(Biz!T biz)
     {
         // ...
     }


     int main()
     {
         auto biz = new Biz!int(123);
         spawn(&addToBiz, biz);
     }
This is a really bad error message. The actual problem here is that you can't take the address of a template without instantiating it first. To make your example work, replace `&addToBiz` with `&addToBiz!int`, like this: spawn(&addToBiz!int, biz);
Nov 08 2023
parent reply Bienlein <fm2002 web.de> writes:
On Wednesday, 8 November 2023 at 16:47:02 UTC, Paul Backus wrote:
 On Wednesday, 8 November 2023 at 16:30:49 UTC, Bienlein wrote:
 ...
 The actual problem here is that you can't take the address of a 
 template without instantiating it first. To make your example 
 work, replace `&addToBiz` with `&addToBiz!int`, like this:

     spawn(&addToBiz!int, biz);
Thanks, Paul. This helped a step further. When applying your change it looks like this: Biz!int biz = new Biz!int(123); spawn(&addToBiz!int, biz); Then I get this error: 'Error: static assert: "Aliases to mutable thread-local data not allowed."' For this error I found this in the Internet: https://stackoverflow.com/questions/14395018/aliases-to-mutable-thread-local-data-not-allowed But this change, did not help: spawn(&addToBiz!int, cast(shared) biz); Then I moved "Biz!int biz = new Biz!int(123);" out of the main function. Compiler complains about static this. Okay, then the code outside the main function now looks this way: class Biz(T) { private T value; this(T value) { this.value = value; } } static void addToBiz(T)(Biz!T biz) { // ... } Biz!int biz; static this() { biz = new Biz!int(123); } int main() { // ... } However, this results in no gain as the compiler now shows the initial error again: 'Error: static assert: "Aliases to mutable thread-local data not allowed."' Everything I tried on my own was also to no avail. If someone could gould give me a hint again ... ;-) Thank you.
Nov 09 2023
parent reply Bienlein <fm2002 web.de> writes:
On Thursday, 9 November 2023 at 09:40:47 UTC, Bienlein wrote:
 On Wednesday, 8 November 2023 at 16:47:02 UTC, Paul Backus 
 wrote:
 On Wednesday, 8 November 2023 at 16:30:49 UTC, Bienlein wrote:
 ...
 The actual problem here is that you can't take the address of 
 a template without instantiating it first. To make your 
 example work, replace `&addToBiz` with `&addToBiz!int`, like 
 this:

     spawn(&addToBiz!int, biz);
Thanks, Paul. This helped a step further. When applying your change it looks like this: Biz!int biz = new Biz!int(123); spawn(&addToBiz!int, biz); Then I get this error: 'Error: static assert: "Aliases to mutable thread-local data not allowed."' For this error I found this in the Internet: https://stackoverflow.com/questions/14395018/aliases-to-mutable-thread-local-data-not-allowed But this change, did not help: spawn(&addToBiz!int, cast(shared) biz); Then I moved "Biz!int biz = new Biz!int(123);" out of the main function. Compiler complains about static this. Okay, then the code outside the main function now looks this way: class Biz(T) { private T value; this(T value) { this.value = value; } } static void addToBiz(T)(Biz!T biz) { // ... } Biz!int biz; static this() { biz = new Biz!int(123); } int main() { // ... } However, this results in no gain as the compiler now shows the initial error again: 'Error: static assert: "Aliases to mutable thread-local data not allowed."' Everything I tried on my own was also to no avail. If someone could gould give me a hint again ... ;-) Thank you.
If I supply a callback function with the parameter not being an instance from a parameterized class I get the same error. The problem seems to be that the parameter of the callback function takes on object as a parameter and not a built-in type like int or String. The samples on how to use the spawn function on dlang.org does not contain a sample on how to get things to work with a objecgt being supllied as parameter to the callback function
Nov 09 2023
parent Bienlein <fm2002 web.de> writes:
On Thursday, 9 November 2023 at 10:14:46 UTC, Bienlein wrote:
 On Thursday, 9 November 2023 at 09:40:47 UTC, Bienlein wrote:
 On Wednesday, 8 November 2023 at 16:47:02 UTC, Paul Backus 
 wrote:
 On Wednesday, 8 November 2023 at 16:30:49 UTC, Bienlein wrote:
 ...
 The actual problem here is that you can't take the address of 
 a template without instantiating it first. To make your 
 example work, replace `&addToBiz` with `&addToBiz!int`, like 
 this:

     spawn(&addToBiz!int, biz);
All right. It seems I cannot pass on an object. So I store the object in a global and access it from the callback function passed to spawn.
Nov 09 2023