Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Компиляция с включенной оптимизацией выносит промежуточную переменную за тело цикла #602

Open
DarthSidius opened this issue Mar 24, 2014 · 5 comments

Comments

@DarthSidius
Copy link
Contributor

using System;
using System.Console;

class cls
{
    public Value : string
    {
        get { "aaaaa!" }
    }
}

class cls1
{
    public Item[num : int] : cls
    {
        get { if( num == 1 ) cls() else null }
    }
}

module Program
{
    Main() : void
    {
        def o = cls1();
        foreach( i in array[1, 2] ) {
            WriteLine(o[i]?.Value); 
        }
    }
}

The output should be:

aaaaa!

Got in release:

aaaaa!
aaaaa!

In debug the output is correct.

@liviuu
Copy link

liviuu commented Mar 25, 2014

Using reflector, it seems that in RELEASE mode the variable str is moved to FUNCTION scope instead of local loop scope. This is the cause of the error. So it must be a bug in Nemerle compiler or ?. macro

private static void Main()
{
    string str = null;  //<---- ERROR this variable should be LOCAL in LOOP
    Program.cls1 cls2 = new Program.cls1();
    for (list<int> tl = new list<int>.Cons(1, new list<int>.Cons(2, new list<int>.Cons(3, new list<int>.Cons(4, list<int>.Nil._N_constant_object)))); tl is list<int>.Cons; tl = tl)
    {
        int hd = ((list<int>.Cons) tl).hd;
        tl = ((list<int>.Cons) tl).tl;
        Program.cls cls = cls2[hd];
        if (cls != null)
        {
            str = cls.Value;
        }
        Console.WriteLine(str);
    }
}

@liviuu
Copy link

liviuu commented Mar 25, 2014

This is how the program look correctly in DEBUG mode. The str variable is loop local.
This issue is very troubling, what is the stability of the Nemerle compiler is someone decides to use it for production code?

private static void Main()
{
    list<int> tl;
    Program.cls1 cls = new Program.cls1();
    for (list<int> list = new list<int>.Cons(1, new list<int>.Cons(2, new list<int>.Cons(3, new list<int>.Cons(4, list<int>.Nil._N_constant_object)))); list is list<int>.Cons; list = tl)
    {
        int hd = ((list<int>.Cons) list).hd;
        tl = ((list<int>.Cons) list).tl;
        int num2 = hd;
        Program.cls cls2 = cls[num2];
        string str2 = null;
        if (cls2 != null)
        {
            str2 = cls2.Value;
        }
        string str = str2;
        Console.WriteLine(str);
    }
}

@DarthSidius
Copy link
Contributor Author

Release:

  private static void Main()
  {
    string str = (string) null;  // Release (!)
    cls1 cls1 = new cls1();
    int[] numArray1 = new int[2];
    int index1 = 0;
    int num1 = 1;
    numArray1[index1] = num1;
    int index2 = 1;
    int num2 = 2;
    numArray1[index2] = num2;
    int[] numArray2 = numArray1;
    int index3 = 0;
    while (index3 < numArray2.Length)
    {
      int index4 = numArray2[index3];
      cls cls = cls1[index4];
      if (cls != null)
        str = cls.Value;
      Console.WriteLine(str);
      checked { ++index3; }
    }
  }

Debug:

  private static void Main()
  {
    cls1 cls1 = new cls1();
    int[] numArray1 = new int[2];
    int index1 = 0;
    int num1 = 1;
    numArray1[index1] = num1;
    int index2 = 1;
    int num2 = 2;
    numArray1[index2] = num2;
    int[] numArray2 = numArray1;
    int index3 = 0;
    while (index3 < numArray2.Length)
    {
      int index4 = numArray2[index3];
      cls cls = cls1[index4];
      string str = (string) null;  // OK
      if (cls != null)
        str = cls.Value;
      Console.WriteLine(str);
      checked { ++index3; }
    }
  }

@DarthSidius
Copy link
Contributor Author

liviuu, don't panic, this is work correct

    Main() : void
    {
        def o = cls1();
        foreach( i in array[1, 2] ) {
            def temp = o[i];
            when( temp != null ) {
                WriteLine(temp.Value); 
            }
        }
    }

I think, bug will fixed soon

@liviuu
Copy link

liviuu commented Mar 25, 2014

So, the problem is the ?. macro that creates the temporary variable in wrong scope?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants