Bug 3926 – opCast(bool) in classes is bug-prone

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2010-03-10T08:01:15Z
Last change time
2022-12-19T15:37:59Z
Assigned to
No Owner
Creator
bearophile_hugs

Comments

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.