Jump to page: 1 2
Thread overview
[Issue 3835] New: [CTFE] Fragile CTFE
Feb 19, 2010
Don
Mar 01, 2010
Serg Kovrov
Mar 09, 2010
Don
[Issue 3835] ref foreach does not work in CTFE
Mar 10, 2010
Don
Feb 06, 2011
klickverbot
Feb 07, 2011
Don
Apr 09, 2011
Don
February 18, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835

           Summary: [CTFE] Fragile CTFE
           Product: D
           Version: 2.040
          Platform: Other
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2010-02-18 13:06:33 PST ---
This code (that uses CTFE to do something that can be useful, it initializes an array with values compiled at compile time) compiles and works correctly, but I think it's too much fragile: if you change the for loop a little, or other details in genFactorials(), the program stops compiling:

int factorial(int n) {
    if (n == 0)
       return 1;
    return n * factorial(n - 1);
}

int[] genFactorials(int n) {
    int[] result;
    for (; n >= 0; --n)
        result = factorial(n) ~ result;
    return result;
}

const int N = 13;
static const auto factorials = cast(int[N])genFactorials(N - 1);
void main() {}


If you need them, I can show many variants of this program that don't
compile/work.
I think to be useful in real programs CTFE has to be less fragile than this.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 19, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug@yahoo.com.au


--- Comment #1 from Don <clugdbug@yahoo.com.au> 2010-02-18 21:14:53 PST ---
(In reply to comment #0)
> This code (that uses CTFE to do something that can be useful, it initializes an array with values compiled at compile time) compiles and works correctly, but I think it's too much fragile: if you change the for loop a little, or other details in genFactorials(), the program stops compiling:

Please put in an example that it wouldn't compile!

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 19, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835



--- Comment #2 from bearophile_hugs@eml.cc 2010-02-19 04:24:33 PST ---
> Please put in an example that it wouldn't compile!

OK. This two versions of genFactorials print the wrong results:
0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0


import std.stdio: writeln;

int factorial(int n) {
    if (n == 0)
       return 1;
    return n * factorial(n - 1);
}

int[] genFactorialsA(int n) {
    int[] result = new int[n + 1];
    foreach (i, ref el; result)
        el = factorial(i);
    return result;
}

int[N] genFactorialsB(int N)() {
    int[N] result;
    foreach (i, ref el; result)
        el = factorial(i);
    return result;
}

enum int N = 13;
static enum auto factorials1 = cast(int[N])genFactorialsA(N - 1);
enum auto factorials2 = genFactorialsB!13;
void main() {
    writeln(factorials1);
    writeln(factorials2);
}


This version doesn't compile, the compiler raises:
test7b.d(7): Error: pure function 'factorial' cannot call impure function
'factorial'

test7b.d(12): Error: pure function 'genFactorials' cannot call impure function
'factorial'

test7b.d(17): Error: cannot evaluate genFactorials(12) at compile time
test7b.d(17): Error: cannot evaluate genFactorials(12) at compile time



import std.stdio: writeln;

pure int[] genFactorials(int n) {
    pure static int factorial(int n) {
        if (n == 0)
           return 1;
        return n * factorial(n - 1);
    }

    int[] result = new int[n + 1];
    foreach (i; 0 .. n+1)
        result[i] = factorial(i);
    return result;
}

enum int N = 13;
static enum auto factorials = cast(int[N])genFactorials(N - 1);
void main() {
    writeln(factorials);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 01, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835


Serg Kovrov <kovrov+puremagic@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kovrov+puremagic@gmail.com


--- Comment #3 from Serg Kovrov <kovrov+puremagic@gmail.com> 2010-03-01 15:09:52 PST ---
Looks like foreach do not work in CTFE. Here is example with two equivalent functions, one uses 'for', other 'foreach' loops:


 uint[256] crc32_table_for()
 {
     uint[256] table;
     for (uint i = 0; i < 256; ++i) {
         uint crc = i;
         for (int j = 0; j < 8; j++)
             crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320 : crc >> 1;
         table[i] = crc;
     }
     return table;
 }

 uint[256] crc32_table_foreach()
 {
     uint[256] table;
     foreach (n, ref i; table) {
         uint crc = n;
         foreach (j; 0 .. 8)
             crc = crc & 1 ? (crc >> 1) ^ 0xEDB88320 : crc >> 1;
         i = crc;
     }
     return table;
 }

 immutable crc32_table1 = crc32_table_for();
 immutable crc32_table2 = crc32_table_foreach();

 import std.stdio;
 void main()
 {
     writefln("%s", crc32_table1);
     writefln("%s", crc32_table2);
     assert (crc32_table1 == crc32_table2);
 }

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 01, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835



--- Comment #4 from bearophile_hugs@eml.cc 2010-03-01 15:56:48 PST ---
I think foreach(x; items) works in CTFE, but foreach(ref x; items) doesn't work
well.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 07, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835



--- Comment #5 from bearophile_hugs@eml.cc 2010-03-07 10:27:14 PST ---
The first two cases are already present in bug 2411. I don't know about the third.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 09, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835



--- Comment #6 from Don <clugdbug@yahoo.com.au> 2010-03-09 04:32:40 PST ---
I created bug 3912 for the third bug mentioned in the comments, which has nothing to do with CTFE. Maybe this bug can now be marked as a duplicate of bug 2411?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 09, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835



--- Comment #7 from bearophile_hugs@eml.cc 2010-03-09 04:45:06 PST ---
You can mark this as duplicate. But when an improvement is created, it's necessary to try it with *all* duplicated examples too, because you must be sure they are really problems with the same cause.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 10, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |rejects-valid
            Summary|[CTFE] Fragile CTFE         |ref foreach does not work
                   |                            |in CTFE


--- Comment #8 from Don <clugdbug@yahoo.com.au> 2010-03-10 11:24:04 PST ---
Bug 2411 is NOT the same as this. (2411 does not involve CTFE). Changing title.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 10, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3835



--- Comment #9 from bearophile_hugs@eml.cc 2010-04-10 16:19:46 PDT ---
In dmd 2.043 my second tests cases works:

import std.stdio: writeln;

pure int[] genFactorials(int n) {
    pure static int factorial(int n) {
        if (n == 0)
           return 1;
        return n * factorial(n - 1);
    }

    int[] result = new int[n + 1];
    foreach (i; 0 .. n+1)
        result[i] = factorial(i);
    return result;
}

enum int N = 13;
static enum auto factorials = cast(int[N])genFactorials(N - 1);
void main() {
    writeln(factorials);
}


The first test case doesn't work yet.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2