Thread overview
mixin under -betterC
Nov 23
DLearner
Nov 26
DLearner
Nov 23
DLearner
Nov 23
DLearner
Dec 09
DLearner
Nov 26
Basile B.
November 23

Code below is intended to test simple mixin with lambda function under -betterC.
Works with full-D, but fails with 'needs GC' errors under -betterC.

Why is this so, bearing in mind the concatenations are executed at
compile, not run, time?

// Test harness

   extern(C) void main() {
      import core.stdc.stdio : printf;
      import testmod;

      bool FirstVarGreater;
      int Var_A = 4;
      int Var_B = 3;


      FirstVarGreater = mixin(mxnTest("Var_A", "Var_B"));
      if (FirstVarGreater) {
            printf("First Var is Greater\n");
      } else {
            printf("First Var is not Greater\n");
      }
   }


// testmod

string mxnTest(string strVar1, string strVar2) {
   return `(int Var1, int Var2) {
      if (Var1 > Var2) {
         return true;
      } else {
         return false;
      }
   }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
}
November 23

On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:

>

Code below is intended to test simple mixin with lambda function under -betterC.
Works with full-D, but fails with 'needs GC' errors under -betterC.

Why is this so, bearing in mind the concatenations are executed at
compile, not run, time?

This is a known limitation: https://issues.dlang.org/show_bug.cgi?id=23637

The easiest way to work around it is to change mxnTest from a function to a templated manifest constant:

enum mxnTest(string strVar1, string strVar2) =
    `(int Var1, int Var2) {
        if (Var1 > Var2) {
           return true;
        } else {
           return false;
        }
    }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;

Keep in mind that you will also have to change the call site to pass "Var_A" and "Var_B" as template arguments:

    // Note the ! in front of the argument list
    FirstVarGreater = mixin(mxnTest!("Var_A", "Var_B"));
November 23

On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:

>

Why is this so, bearing in mind the concatenations are executed at
compile, not run, time?

If you compile without -betterC, it'll work, but if you examine the result you'll find that the mxnTest function is still compiled into the result. D makes it so convenient to use functions at compile-time that there's no clear distinction for functions that should only exist at compile-time.

Make mxnTest a template:

string mxnTest()(string strVar1, string strVar2) {
              ^^
November 23

On Thursday, 23 November 2023 at 17:03:29 UTC, Julian Fondren wrote:

>

On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:

>

Why is this so, bearing in mind the concatenations are executed at
compile, not run, time?

If you compile without -betterC, it'll work, but if you examine the result you'll find that the mxnTest function is still compiled into the result. D makes it so convenient to use functions at compile-time that there's no clear distinction for functions that should only exist at compile-time.

Make mxnTest a template:

string mxnTest()(string strVar1, string strVar2) {
              ^^

I tried what you suggested, and with no other changes it compiled and ran correctly.
Thanks!

I just find it surprising that your suggestion worked, but the (slightly simpler) earlier version did not.

November 23

On Thursday, 23 November 2023 at 17:46:55 UTC, DLearner wrote:

>

I just find it surprising that your suggestion worked, but the (slightly simpler) earlier version did not.

The enum answer? That also works, but you have to make a change at the callsite as well, to mixin(mxnTest!("Var_A", "Var_B")); - passing the strings as template rather than functional arguments.

November 23

On Thursday, 23 November 2023 at 18:54:09 UTC, Julian Fondren wrote:
[...]

>

The enum answer?
[...]

No, the 'template' answer.
To me, if the 'template' suggestion worked (as it did), then my simple mixin (as in my original post) should also work.

November 26

On Thursday, 23 November 2023 at 17:02:58 UTC, Paul Backus wrote:
[...]

>

This is a known limitation: https://issues.dlang.org/show_bug.cgi?id=23637

[...]

Sorry to come back to this, but the reference above suggests not a bug in the compiler.

If not a bug in the compiler, please, what is going on?
I repeat that the only possible trigger I see for the GC
are the ~ that happen at compile, not run, time.

November 26
On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:
> string mxnTest(string strVar1, string strVar2) {
>    return `(int Var1, int Var2) {
>       if (Var1 > Var2) {
>          return true;
>       } else {
>          return false;
>       }
>    }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
> }
> ```

This function exists at runtime. Another module could, in theory, import it and call it. A shared library could, in theory, export it. You used it at compile time, but the function is available for other users too.

betterC doesn't know the difference between theory and practice.
November 26

On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:

>

Code below is intended to test simple mixin with lambda function under -betterC.
Works with full-D, but fails with 'needs GC' errors under -betterC.

Why is this so, bearing in mind the concatenations are executed at
compile, not run, time?

// Test harness

   extern(C) void main() {
      import core.stdc.stdio : printf;
      import testmod;

      bool FirstVarGreater;
      int Var_A = 4;
      int Var_B = 3;


      FirstVarGreater = mixin(mxnTest("Var_A", "Var_B"));
      if (FirstVarGreater) {
            printf("First Var is Greater\n");
      } else {
            printf("First Var is not Greater\n");
      }
   }


// testmod

string mxnTest(string strVar1, string strVar2) {
   return `(int Var1, int Var2) {
      if (Var1 > Var2) {
         return true;
      } else {
         return false;
      }
   }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
}

You've been explained the reason why that does not work, note however that it's not hopeless see

unfortunately the PR is stalled since two months.

December 09

On Sunday, 26 November 2023 at 15:35:39 UTC, Adam D Ruppe wrote:

>

On Thursday, 23 November 2023 at 16:33:52 UTC, DLearner wrote:

>

string mxnTest(string strVar1, string strVar2) {
return (int Var1, int Var2) { if (Var1 > Var2) { return true; } else { return false; } }( ~ strVar1 ~ , ~ strVar2 ~ );
}

This function exists at runtime. Another module could, in theory, import it and call it. A shared library could, in theory, export it. You used it at compile time, but the function is available for other users too.

betterC doesn't know the difference between theory and practice.

From your comments and others on this thread:

// Test harness

   extern(C) void main() {
      import core.stdc.stdio : printf;
      import testmod;

      bool FirstVarGreater;
      int Var_A = 6;
      int Var_B = 5;


      FirstVarGreater = mixin(mxnTest("Var_A", "Var_B"));
      if (FirstVarGreater) {
            printf("First Var is Greater\n");
      } else {
            printf("First Var is not Greater\n");
      }
   }

// testmod

string mxnTest(string strVar1, string strVar2) {

   if (__ctfe) {
      return `(int Var1, int Var2) {
         if (Var1 > Var2) {
            return true;
         } else {
            return false;
         }
      }(` ~ strVar1 ~ `,` ~ strVar2 ~ `)`;
   } else {
      return ``;
   }
}

Works, avoid templates + -betterC compliant, but to me clumsy.