Bug 15153 – CTFE failes to access second dimension of static arrays

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2015-10-04T15:31:00Z
Last change time
2015-10-04T20:29:27Z
Assigned to
nobody
Creator
tobias.marstaller

Attachments

IDFilenameSummaryContent-TypeSize
1553report.dBoth snippets with compiler outputtext/plain577

Comments

Comment #0 by tobias.marstaller — 2015-10-04T15:31:17Z
Created attachment 1553 Both snippets with compiler output CTFE fails to access the second dimension of static arrays (even if explicitly given). This snipped throws the compiler error "variable nCols cannot be read at compile time.": -------------------------------------------------------------------------------- static int[][] staticTable = [[1, 2], [3, 4]]; static int[][] staticallyDerivedTable = deriveTable(staticTable); static int[][] deriveTable(int[][] table) { int nRows = table.length; int nCols = table[0].length; int[nCols][nRows] newTable; // ... do something return newTable; } -------------------------------------------------------------------------------- The error occurs in deriveTable(int[][]) where newTable is declared. But even if the array sizes are explicitly given, the error stays: -------------------------------------------------------------------------------- static int[2][2] staticTable = [[1, 2], [3, 4]]; static int[2][2] staticallyDerivedTable = deriveTable(staticTable); static int[2][2] deriveTable(int[2][2] table) { int nRows = table.length; int nCols = table[0].length; int[nCols][nRows] newTable; // ... do something return newTable; } -------------------------------------------------------------------------------- This might be related to #2569; AFAICT my code is correct; in both cases the required information is available at compile time. table.length does not throw an error so i guess the basics are working fine already. Since the staticTable is of fixed size, this is not that much of an issue to me because i can hard-code the sizes; but that should not be required.
Comment #1 by ag0aep6g — 2015-10-04T18:51:48Z
(In reply to tobias.marstaller from comment #0) > But even if the array sizes are explicitly given, the error stays: > > ----------------------------------------------------------------------------- > --- > static int[2][2] staticTable = [[1, 2], [3, 4]]; > static int[2][2] staticallyDerivedTable = deriveTable(staticTable); > > static int[2][2] deriveTable(int[2][2] table) > { > int nRows = table.length; > int nCols = table[0].length; > int[nCols][nRows] newTable; > > // ... do something > > return newTable; > } > ----------------------------------------------------------------------------- > --- > > > This might be related to #2569; > > AFAICT my code is correct; in both cases the required information is > available > at compile time. table.length does not throw an error so i guess the basics > are working fine already. It's true that table.length is a static value. It's known at compile time, and the compiler is aware of that. You can use it for static array lengths. But nRows is a run time variable. Its value may actually be a compile time constant, but the compiler doesn't try to find out. This is working as designed. You can use enums instead of variables: ---- enum int[2][2] staticTable = [[1, 2], [3, 4]]; static int[2][2] staticallyDerivedTable = deriveTable(staticTable); static int[2][2] deriveTable(int[2][2] table) { enum size_t nRows = table.length; enum size_t nCols = table[0].length; int[nCols][nRows] newTable; // ... do something return newTable; } ---- I'm closing this as INVALID. Please reopen and/or make a thread on http://forum.dlang.org/group/general if you disagree.
Comment #2 by tobias.marstaller — 2015-10-04T19:46:23Z
Okey, i understand that. I changed my test snippet to this but the compiler still gives an error for the array declaration: ---- module std.test; static int[][] staticTable = [[1, 2], [3, 4]]; static int[][] staticallyDerivedTable = deriveTable(staticTable); static int[][] deriveTable(int[][] table) { int[table.length][table[0].length] newTable; // ... do something return newTable; } ---- I switchted to use a dynamic array, which works: ---- module std.test; static int[][] staticTable = [[1, 2], [3, 4]]; static int[][] staticallyDerivedTable = deriveTable(staticTable); static int[][] deriveTable(int[][] table) { int[][] newTable = new int[][](table[0].length, table.length); // ... do something return newTable; } ----
Comment #3 by ag0aep6g — 2015-10-04T20:15:19Z
(In reply to tobias.marstaller from comment #2) > Okey, i understand that. I changed my test snippet to this but the compiler > still gives an error for the array declaration: > > ---- > module std.test; > > static int[][] staticTable = [[1, 2], [3, 4]]; > static int[][] staticallyDerivedTable = deriveTable(staticTable); > > static int[][] deriveTable(int[][] table) > { > int[table.length][table[0].length] newTable; > > // ... do something > > return newTable; > } > ---- Here `table` is a dynamic array. That makes `table.length` a dynamic value. Again, it may actually be a constant, but the compiler doesn't try that. It's really the same scenario as before. CTFE follows the same rules as run time evaluation (plus some additional restrictions). When some code doesn't compile for run time, then it's not supposed to work in CTFE. I'd like to suggest you make a thread on the learn group (<http://forum.dlang.org/group/learn>) if the rules of CTFE are maybe still a bit foggy for you. Or make a thread on the general group (<http://forum.dlang.org/group/general>) if you feel that the rules as they are could be improved. And if you feel that the documentation is not explaining the details of CTFE properly, feel free to file an issue on that, of course. I'm not closing again to avoid back and forth status changes. I'm confident that everything works as designed, though. If you agree that the issue is invalid, please let me know, or just close it yourself.