[Issue 8823] New: static if (A || B) != static if (A) else if (B) in some cases
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Sun Oct 14 23:29:23 PDT 2012
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 at puremagic.com
ReportedBy: beatgammit at gmail.com
--- Comment #0 from Jameson <beatgammit at 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: -------
More information about the Digitalmars-d-bugs
mailing list