Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents
Part Five.  Operators


Chapter 30. Short-circuit!

The && and || operators provide a Boolean evaluation of the two expressions, as in:



if(x && y) // Evaluates to true if both x and y are true


if(x || y) // Evaluates to true if either x or y are true



Both these operators have what is known as short-circuit evaluation semantics [Stro1997]. Since the && operator provides a logical AND of the two arguments, there is no need to evaluate the second argument if the first is false. Conversely, for the || operator, which provides a logical OR of its arguments, the second argument does not need to be evaluated if the first is true. Since C is all about efficiency, the second arguments are only evaluated when they are needed. This is a very useful facility since it allows us to write succinct yet safe conditional expressions:



if( !str.empty() &&


    str[0] == '[')



However, the short-circuit nature of the operators is not respected when they are overloaded with one or both arguments being of class type. The following code might or might not print out its plaintiff cry, depending on whether the required overloaded operator &&() arguments are of type bool and Y const& or bool and X const&:



class X


{};





class Y


{


public:


  operator X() const


  {


    printf("Why am I called?\n");


    return X();


  }


};





Y y;





if(false && y)


{}



This is a fundamental change in semantics that is almost impossible to detect by looking at the code.

Imperfection: Overloading the && and || operators for class types represents an invisible breaking of short-circuit evaluation.


This is definitely one to be avoided. Thankfully the need to do so is very rare: I've not had occasion to do it, other than for research, in over ten years of C++ programming, and the chances are that you won't need to do so either. If you do, you must be aware of the potential side effects from the change in semantics.


      Previous section   Next section