Bug 1245 – static foreach shouldn't define new scope and introduce new variables

Status
RESOLVED
Resolution
FIXED
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2007-05-23T15:37:00Z
Last change time
2014-02-16T15:23:04Z
Keywords
rejects-valid
Assigned to
nobody
Creator
witold.baryluk+d

Comments

Comment #0 by witold.baryluk+d — 2007-05-23T15:37:59Z
import std.stdio; void Code(x...)() { foreach (i, xi; x) { static if (xi != 0) { // dosn't works, see below //static if (x[i] != 0) { // workaround writefln(xi); } } } void main() { alias Code!(1, 6, 0, 2, 5) c; c(); } // staticforeachif.d(5): Error: expression xi != 0 is not constant // or does not evaluate to a bool with workaround, it works, and display: 1 6 2 5 as needed Imho foreach over tupple shouldn't introduce new scope and variables xi, but as static if be in the same scope (if needed you always can add { .. } and xi (second parameter in foreach), should be actually alias to x[i] I'm using this in optimalisation of general code generators.
Comment #1 by smjg — 2007-05-25T04:48:06Z
Huh? What is a "static foreach"? If there's any reference to it in the spec, it isn't obvious.
Comment #2 by witold.baryluk+d — 2007-05-25T08:05:09Z
http://www.digitalmars.com/d/tuple.html Looping section. Foreach over tuple works like static foreach, and it is unrolled in compile time.
Comment #3 by smjg — 2007-05-25T11:49:05Z
I see. But I'm not sure I see how it would work to make foreach not define a scope in such circumstances. OTOH, I agree that xi should be recognised as constant.
Comment #4 by shro8822 — 2007-05-25T12:17:17Z
The issue I have is that int the foreach loop the value of i gets pushed onto the stack. (I was looking at the ASM dump from DMD linux) foreach(i, j; T!(1,2,3) { asm{nop;}; } should compeile to nop; nop; nop;
Comment #5 by witold.baryluk+d — 2007-05-29T00:27:31Z
Another example: module staticforeach_switch; import std.stdio; template Tuple(E...) { alias E Tuple; } alias Tuple!(101.0, 102.0, 103.0, 104.0) coef; double f(int l, double x) { switch (l) { foreach (i, a_i; coef) { case i: //return x*a_i; // compiles and gives garbage return x*coef[i]; // works } default: assert(0); } assert(0); } void main() { writefln(f(3, 2.0)); // 2*104 = 208 }
Comment #6 by witold.baryluk+d — 2009-11-18T21:41:58Z
I just tested this both my codes (from "Description" and "Comment 5") in DMD 2.032, and they works correctly! (only switch isn't full optimal in asm, but this not conected with this bug). BCS's example with nop's is also not optimal, there are some operations on EBP register: mov dword ptr -034h[EBP],1 nop mov dword ptr -02Ch[EBP],2 nop mov dword ptr -024h[EBP],3 nop mov dword ptr -01Ch[EBP],5 nop mov dword ptr -014h[EBP],6 nop mov dword ptr -0Ch[EBP],7 nop I don't remember any changelog entry mentioning anything about foreach over tuples... Anyone want to enlighten me? :) And what about DMD 1.x?
Comment #7 by bearophile_hugs — 2010-04-12T17:52:10Z
This is now fixed in DMD 1.058 and 2.043.