Comment #0 by bearophile_hugs — 2010-03-10T08:01:15Z
A opCast(bool) operator present in struct is called automatically in a if(x), but the same is not true if x is a class.
So for example if you modify your code changing a struct into a class, other parts of the program will silently stop working (it usually return true if the class reference is not null). This is a problem, because it's bug-prone.
This shows the situation:
import std.stdio: writeln;
struct FooStruct {
int x;
T opCast(T:bool)() {
return this.x != 0;
}
}
class FooClass {
int x;
this(int xx) { this.x = xx; }
static FooClass opCall(int xx) { return new FooClass(xx); }
T opCast(T:bool)() {
return this.x != 0;
}
}
void main() {
enum int N = 0;
auto fstruct = FooStruct(N);
if (fstruct)
writeln("fstruct true");
else
writeln("fstruct false"); // fstruct false
auto fclass = FooClass(N);
if (fclass)
writeln("fclass true"); // fclass true
else
writeln("fclass false");
if (cast(bool)fclass)
writeln("fclass true");
else
writeln("fclass false"); // fclass false
}
A possible simple solution is to selectively disallow opCast(bool) for classes. So an hypothetical conversion of a struct to a class raises a compile time error that helps avoid bugs. But this makes it impossible to have cast(bool) on classes. I don't know how often a cast(bool) can be useful in a class (probably not often).
Another possible solution is to keep allowing cast(bool) in classes, but have if(fclass) call opCast(bool) for classes too, avoiding the asymmetry between structs and classes. But this requires to write if(fclass is null) to test the value of the object reference.
This problem has to be faced soon, because later it will become impossible to fix.
Comment #1 by razvan.nitu1305 — 2022-12-19T15:37:59Z
This is an enhancement request as the spec clearly states that for boolean operations only structs will implicitly call opCast: https://dlang.org/spec/operatoroverloading.html#boolean_operators (point 3). Indeed, if a struct is transitioned to a class this is problematic, however, other problems might appear also (for example, equality comparisons). Therefore, I don't think this is a good argument for implementing this and most likely this might silently change the behavior of a lot of code.
One solution would be to have a third party tool (like D-Scanner) implement a check for class instances that are used in if conditions and also define an opCast. A warning could be issued then.