digitalmars.D.bugs - [Issue 8823] New: static if (A || B) != static if (A) else if (B) in some cases
- d-bugmail puremagic.com (103/103) Oct 14 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8823
- d-bugmail puremagic.com (53/53) Oct 15 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8823
- d-bugmail puremagic.com (17/17) Oct 15 2012 http://d.puremagic.com/issues/show_bug.cgi?id=8823
http://d.puremagic.com/issues/show_bug.cgi?id=8823 Summary: static if (A || B) != static if (A) else if (B) in some cases Product: D Version: D2 Platform: All OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody puremagic.com ReportedBy: beatgammit gmail.com --- Comment #0 from Jameson <beatgammit gmail.com> 2012-10-14 23:29:18 PDT --- Test platform: Fedora 17 Linux 3.5.4-2.fc17.x86_64 DMD64 D Compiler v2.060 rdmd build 20120724 The following works: import std.stdio; class A { string s; } void main() { A a = new A; foreach (t; __traits(allMembers, A)) { static if ( is(typeof(__traits(getMember, A, t)) == function) || is(typeof(__traits(getMember, a, t)) == function) || t == "Monitor" ) { continue; } __traits(getMember, a, t) = "hello"; } } But if I split up the static if, it won't compile: import std.stdio; class A { string s; } void main() { A a = new A; foreach (t; __traits(allMembers, A)) { static if (is(typeof(__traits(getMember, A, t)) == function)) { continue; } else if (is(typeof(__traits(getMember, a, t)) == function)) { continue; } else if (t == "Monitor") { continue; } writeln(t); __traits(getMember, a, t) = "hello"; // error } } I get the following errors: test.d(19): Error: not a property a.toString test.d(19): Error: not a property a.toHash test.d(19): Error: not a property a.opCmp test.d(19): Error: not a property a.opEquals test.d(19): Error: __traits(getMember,a,"Monitor") is not an lvalue If I comment out the offending line, I only get "s" as output, as expected. Also, if I use an else branch instead, I still get a compile error: import std.stdio; class A { string s; } void main() { A a = new A; foreach (t; __traits(allMembers, A)) { static if (is(typeof(__traits(getMember, A, t)) == function)) { continue; } else if (is(typeof(__traits(getMember, a, t)) == function)) { continue; } else if (t == "Monitor") { continue; } else { writeln(t); __traits(getMember, a, t) = "hello"; // error } } } test.d(18): Error: __traits(getMember,a,"Monitor") is not an lvalue This is even more curious, because I explicitly accounted for this case (and it works in the combined static if). As in the above example, commenting out the offending line works as expected. What did I expect: The if/else branches would behave the same at compile time as it's runtime equivalent. __traits(getMember, a, t) should not be evaluated if any of the above if/else branches are true, since it would be an unreachable statement given the continue. I was very surprised that combining them into one if conditional worked as expected, but if one works, they all should work. Notes: I'm building a marshaller, so only data types should be considered. Since there is no isVariable for __traits, this must be done in a loop. Many of the members cannot be marshalled, so this makes for a messy if conditional, so splitting it up (into checks on static/instance members) can be more readable. This particular case can be easily avoided, but a more complicated case (one branch continues and another breaks) would not be so easy to rectify. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 14 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8823 --- Comment #1 from Jameson <beatgammit gmail.com> 2012-10-15 07:44:35 PDT --- It also does not work reliably if I change them to regular if blocks: import std.stdio; class A { string s; } void main() { A a = new A; foreach (t; __traits(allMembers, A)) { static if (is(typeof(__traits(getMember, A, t)) == function)) { continue; } static if (is(typeof(__traits(getMember, a, t)) == function)) { continue; } static if (t == "Monitor") { continue; } __traits(getMember, a, t) = "hello"; } } Tt works if I nest under a common else: import std.stdio; class A { string s; } void main() { A a = new A; foreach (t; __traits(allMembers, A)) { static if (is(typeof(__traits(getMember, A, t)) == function)) { continue; } else { static if (is(typeof(__traits(getMember, a, t)) == function)) { continue; } else { static if (t == "Monitor") { continue; } else { __traits(getMember, a, t) = "hello"; } } } } } It seems the workaround is nesting. It looks as if 'else if' in general doesn't work as expected. It serves as a regular 'if', but without the knowledge from the preceding 'if' conditionals. In my implementation, I have more than 5 conditionals (all different bodies), but each assumes that the previous conditionals evaluated to false. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 15 2012
http://d.puremagic.com/issues/show_bug.cgi?id=8823 Dmitry Olshansky <dmitry.olsh gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED CC| |dmitry.olsh gmail.com Resolution| |INVALID --- Comment #2 from Dmitry Olshansky <dmitry.olsh gmail.com> 2012-10-15 09:28:15 PDT --- Basically: static if(...) else static if(...){ } Note the second 'static' before if. Fairly common gotcha. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 15 2012