www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Regarding opCast(bool) class method

reply "bearophile" <bearophileHUGS lycos.com> writes:
I think that now and then it's good to underline some D issues, 
even old ones.

This little program shows the asymmetry in opCast(bool) between 
struct instances and class instances:


struct FooStruct {
     int x;
     this(int xx) { this.x = xx; }
     T opCast(T: bool)() {
         return this.x != 0;
     }
}

class FooClass {
     int x;
     this(int xx) { this.x = xx; }
     T opCast(T: bool)() {
         return this.x != 0;
     }
}

void main() {
     import std.stdio;
     enum int N = 0;

     auto fstruct = FooStruct(N);
     if (fstruct)
         writeln("fstruct true");
     else
         writeln("fstruct false"); //*

     if (cast(bool)fstruct)
         writeln("cast(bool)fstruct true");
     else
         writeln("cast(bool)fstruct false"); //*

     auto fclass = new FooClass(N);

     if (fclass)
         writeln("fclass true"); //*
     else
         writeln("fclass false");

     if (cast(bool)fclass)
         writeln("cast(bool)fclass true");
     else
         writeln("cast(bool)fclass false"); //*
}



The output:

fstruct false
cast(bool)fstruct false
fclass true
cast(bool)fclass false


Is this situation a problem?
If in your code you convert a struct to class or the other way, 
and it contains an opCast(bool), you will have troubles. And 
generally I don't like how opCast(bool) works in classes, I think 
it's a bit bug-prone. I think "if(fclass)" and 
"if(cast(bool)fclass)" should always have the same boolean value.

If this situation is a problem, then here are two of the possible 
solutions:
- Do not allow opCast(bool) in classes. How much often do you 
need cast(bool) on class instances?
- Keep cast(bool) in classes, and remove the asymmetry between 
structs and classes, if possible. So "if(fclass)" on a class 
instance calls opCast(bool). Then to test the value of the 
reference you use "if(fclass is null)".


See also my issue on this:
http://d.puremagic.com/issues/show_bug.cgi?id=3926

More info on related matters in C++/C++11:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_conversion_operators
http://www.artima.com/cppsource/safeboolP.html
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool

Bye,
bearophile
Nov 08 2012
parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Thu, 08 Nov 2012 23:04:17 -0000, bearophile <bearophileHUGS lycos.com>  
wrote:
 If this situation is a problem, then here are two of the possible  
 solutions:
 - Do not allow opCast(bool) in classes. How much often do you need  
 cast(bool) on class instances?
I don't like it, it restricts people from defining a class which represents a boolean value/state (and casting it to bool).
 - Keep cast(bool) in classes, and remove the asymmetry between structs  
 and classes, if possible. So "if(fclass)" on a class instance calls  
 opCast(bool). Then to test the value of the reference you use "if(fclass  
 is null)".
This is a breaking change. A slightly less breaking change would be to make "if (fclass)" into both a reference !is null check and a call to any opCast(bool) if it exists. This would then only break existing code using "if (fclass)" on references to classes which define opCast(bool) (which return false). R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 09 2012
parent "bearophile" <bearophileHUGS lycos.com> writes:
Regan Heath:

 This is a breaking change.
Yes, I have several requests that cause tiny breaking changes open in Bugzilla, since years, and they often have had no comments for years. Sometimes breaking little things is better. Bye, bearophile
Nov 09 2012