I don't know how else to describe this. template AA(V, K) { V[K] AA(T...)(T args) { V[K] ret; K key; foreach(i, arg; args) { static if(!(i & 1)) key = arg; else ret[key] = arg; } return ret; } } void main() { char[][char[]] array = AA!(char[], char[])("a", "b", "c", "d"); writefln("length = ", array.length); foreach(k, v; array) writefln("array[", k, "] = ", v); } This code will give bizarre output when printing out the contents of the returned AA. This usually is weird characters, and usually results in a "4invalid UTF-8 sequence" exception. Stranger still, the output changes depending on how many string literals there are in main(). This happens in both -debug and -release modes, although they give different output.
Added to DStress as http://dstress.kuehne.cn/run/o/odd_bug_13_A.d
The equivalent code (below) works correctly on D2. This is a D1-only bug. --------- import std.stdio; template AA(V, K) { V[K] AA(T...)(T args) { V[K] ret; K key; foreach(i, arg; args) { static if(!(i & 1)) key = arg; else ret[key] = arg; } return ret; } } void main() { string[string] array = AA!(string, string)("a", "b"[], "c"[], "d"[]); writefln("length = %d\n", array.length); foreach(k, v; array) writefln("array[%d]=%s", k, v); }
Original title was: "Incorrect codegen with tuples, string constants, and AAs". This bug has nothing to do with AAs, actually. The problem is that the 'value' in a tuple foreach isn't dealt with correctly. Workarounds: Change the code into: ret = arg.dup; or ret = args[0]; char[] bug874(T...)(T args) { char[] ret; foreach(arg; args) { ret = arg; } assert(ret=="b"); // passes return ret; } void main() { char[] s = bug874("b"); assert(s == "b"); // fails }
Looks like this is just a D2 fix which didn't get transferred across to D1. PATCH (against DMD1 svn 227): expression.c, ForeachStatement::semantic, line 1380. // Declare value if (arg->storageClass & (STCout | STCref | STClazy)) error("no storage class for value %s", arg->ident->toChars()); Dsymbol *var; if (te) - { - if (e->type->toBasetype()->ty == Tfunction && - e->op == TOKvar) + { Type *tb = e->type->toBasetype(); + if ((tb->ty == Tfunction || tb->ty == Tsarray) && e->op == TOKvar) { VarExp *ve = (VarExp *)e; var = new AliasDeclaration(loc, arg->ident, ve->var); }
SVN commit: http://www.dsource.org/projects/dmd/changeset/236
Fixed dmd 1.051
AltStyle によって変換されたページ (->オリジナル) / アドレス: モード: デフォルト 音声ブラウザ ルビ付き 配色反転 文字拡大 モバイル