Thread overview
Why do ints defined in template mixins have garbage values?
Dec 11, 2018
Johannes Riecken
Dec 11, 2018
H. S. Teoh
Dec 12, 2018
AlCaponeJr
Dec 12, 2018
H. S. Teoh
Dec 12, 2018
Michelle Long
Dec 12, 2018
Kagamin
Dec 11, 2018
H. S. Teoh
Dec 12, 2018
Johannes Loher
December 11, 2018
Code:

import std.conv;
import std.stdio;

mixin template genInts()
{
  enum arr = [0,1];
  static foreach (t; arr) {
    mixin("int i" ~ to!string(t) ~ " = 5;");
  }
}

void main() {
  mixin genInts!();
  writeln(i0);
  writeln(i1);
}


Expected output:
5
5

Actual output is two garbage integer values.
December 11, 2018
On Tue, Dec 11, 2018 at 09:09:55PM +0000, Johannes Riecken via Digitalmars-d-learn wrote:
> Code:
> 
> import std.conv;
> import std.stdio;
> 
> mixin template genInts()
> {
>   enum arr = [0,1];
>   static foreach (t; arr) {
>     mixin("int i" ~ to!string(t) ~ " = 5;");
>   }
> }
> 
> void main() {
>   mixin genInts!();
>   writeln(i0);
>   writeln(i1);
> }
> 
> 
> Expected output:
> 5
> 5
> 
> Actual output is two garbage integer values.

Whoa.  That looks like a compiler bug. File a bug here:

	https://issues.dlang.org/enter_bug.cgi


T

-- 
There are two ways to write error-free programs; only the third one works.
December 11, 2018
On 12/11/18 4:09 PM, Johannes Riecken wrote:
> Code:
> 
> import std.conv;
> import std.stdio;
> 
> mixin template genInts()
> {
>    enum arr = [0,1];
>    static foreach (t; arr) {
>      mixin("int i" ~ to!string(t) ~ " = 5;");
>    }
> }
> 
> void main() {
>    mixin genInts!();
>    writeln(i0);
>    writeln(i1);
> }
> 
> 
> Expected output:
> 5
> 5
> 
> Actual output is two garbage integer values.

Looks like a bug to me in static foreach.

Using -vcg-ast, it appears that the int definitions do not show up in main.

If I add an int using a regular declaration or a straight mixin("int i0 = 5;"); then the variable shows up.

-Steve
December 11, 2018
P.S.  Just looked at the disassembly.  Seems to be a codegen bug -- the code appears to be trying to lookup local variables (presumably i0 and i1), but somehow the initialization code is missing.


--T

On Tue, Dec 11, 2018 at 09:09:55PM +0000, Johannes Riecken via Digitalmars-d-learn wrote:
> Code:
> 
> import std.conv;
> import std.stdio;
> 
> mixin template genInts()
> {
>   enum arr = [0,1];
>   static foreach (t; arr) {
>     mixin("int i" ~ to!string(t) ~ " = 5;");
>   }
> }
> 
> void main() {
>   mixin genInts!();
>   writeln(i0);
>   writeln(i1);
> }
> 
> 
> Expected output:
> 5
> 5
> 
> Actual output is two garbage integer values.

-- 
"If you're arguing, you're losing." -- Mike Thomas
December 12, 2018
On Tuesday, 11 December 2018 at 21:09:55 UTC, Johannes Riecken wrote:
> Code:
>
> import std.conv;
> import std.stdio;
>
> mixin template genInts()
> {
>   enum arr = [0,1];
>   static foreach (t; arr) {
>     mixin("int i" ~ to!string(t) ~ " = 5;");
>   }
> }
>
> void main() {
>   mixin genInts!();
>   writeln(i0);
>   writeln(i1);
> }
>
>
> Expected output:
> 5
> 5
>
> Actual output is two garbage integer values.

Definitely a compiler bug.

According to https://run.dlang.io/gist/1e6e7574a8762d7fed5a3aa22390493d?compiler=dreg
Garbage values are printed since 2.078.1.

compiling with ldc results in a segmentation fault when running the program: https://run.dlang.io/gist/02780bfe33a2bfd000aa5718a3fe6505?compiler=ldc
December 12, 2018
On Tuesday, 11 December 2018 at 21:17:46 UTC, H. S. Teoh wrote:
> Whoa.  That looks like a compiler bug. File a bug here:
> ...

Genuinely asking if this is a case of lacking of unit test for the Compiler or this is a case that where is hard to test or prevent?

Al.
December 12, 2018
On Tuesday, 11 December 2018 at 21:19:59 UTC, Steven Schveighoffer wrote:
> If I add an int using a regular declaration or a straight mixin("int i0 = 5;"); then the variable shows up.

mixin template genInts()
{
    enum arr = [0];
    static foreach (t; arr)
    {
        mixin("int i0 = 5;");
    }
}

Still prints garbage.
December 12, 2018
On Wed, Dec 12, 2018 at 01:35:00PM +0000, AlCaponeJr via Digitalmars-d-learn wrote:
> On Tuesday, 11 December 2018 at 21:17:46 UTC, H. S. Teoh wrote:
> > Whoa.  That looks like a compiler bug. File a bug here:
> > ...
> 
> Genuinely asking if this is a case of lacking of unit test for the Compiler or this is a case that where is hard to test or prevent?
[...]

I think it's just a case of too many possible combinations of features to test that some inevitably get overlooked.  Combinatorial explosion. But once bug reports like these are filed and fixed, more unittests will be added, which increase the surface area of tested feature combinations and (hopefully) reduce the likelihood of similar bugs.


T

-- 
Talk is cheap. Whining is actually free. -- Lars Wirzenius
December 12, 2018
On 12/12/18 10:22 AM, Kagamin wrote:
> On Tuesday, 11 December 2018 at 21:19:59 UTC, Steven Schveighoffer wrote:
>> If I add an int using a regular declaration or a straight mixin("int i0 = 5;"); then the variable shows up.
> 
> mixin template genInts()
> {
>      enum arr = [0];
>      static foreach (t; arr)
>      {
>          mixin("int i0 = 5;");
>      }
> }
> 
> Still prints garbage.

I meant this:

mixin template genInts()
{
   mixin("int i0 = 5;");
}

It's still a static foreach + mixin + mixin template bug, all those are needed to make it fail.

What's interesting is that dmd thinks there is an i0 (there is no error on a missing symbol), but the ast printed doesn't show a declaration for it.

-Steve
December 12, 2018
On Wednesday, 12 December 2018 at 16:33:02 UTC, H. S. Teoh wrote:
> On Wed, Dec 12, 2018 at 01:35:00PM +0000, AlCaponeJr via Digitalmars-d-learn wrote:
>> On Tuesday, 11 December 2018 at 21:17:46 UTC, H. S. Teoh wrote:
>> > Whoa.  That looks like a compiler bug. File a bug here:
>> > ...
>> 
>> Genuinely asking if this is a case of lacking of unit test for the Compiler or this is a case that where is hard to test or prevent?
> [...]
>
> I think it's just a case of too many possible combinations of features to test that some inevitably get overlooked.  Combinatorial explosion. But once bug reports like these are filed and fixed, more unittests will be added, which increase the surface area of tested feature combinations and (hopefully) reduce the likelihood of similar bugs.
>
>

Proper factorization prevents this. It may be a difficult problem but all it requires is to think before one leaps. People have already developed randomized program testing(essentially generates random but working programs(or non-working for error codes)).  Someone could setup a machine that continuously generates these programs and tests the compiler. Any discrepancies are reported and investigated.