Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ condition without selection statement

Maybe because of Perl influence, I like using the following syntax

condition && do_something();

instead of

if ( condition )
{
  do_something();
}

(I know I could put the latter in one row without braces, but that's not the point.)

I've made several tests (below), which work. But I couldn't find a reference in the standard, stating that it's legal. It could be implied in

  • 5.14 Logical AND operator
  • 5.17 Assignment operators
  • 6.4. Selection statements

but I'm not completely sure (I checked C++ 98, sorry to be old fashioned, but probably even C standard would suffice).

NB: I do realize that in order to work, the last expression (do_something) has also to be be convertible to bool, which is not necessary for the selection statement. This is a serious restriction of course.

So the questions are:

  1. Is it perfectly legal?
  2. Is there a reason not to use it?
  3. Are there possible side effects (like optimizations leading to unexpected results)?

Apologies if turns out to be a duplicate, I couldn't find anything, but possibly because I didn't use the right keywords.

#include <cassert>

bool sayYes()
{
  return true;
}

bool sayNo()
{
  return false;
}

int main( int args, char* argv[] )
{
  bool a = true;
  bool b = false;
  int i = 0;

  a && ( i = 1 );
  assert( i == 1 );

  !a && ( i = 0 );
  assert( i == 1 );

  ( a || b ) && ( i = 0 );
  assert( i == 0 );

  sayYes() && ( i = 1 );
  assert( i == 1 );

  ( sayNo() || sayYes() ) && ( i = 0 );
  assert( i == 0 );

  return 0;
}
like image 371
lafrecciablu Avatar asked Mar 09 '26 05:03

lafrecciablu


2 Answers

It's perfectly legal. From [expr.log.and]:

&& guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

expr() && fun() is equivalent to if (expr()) fun() (assuming fun() returns something convertible to bool). That's an extremely important property when it comes to writing compound conditional expressions. For example, only dereferencing a pointer after we know it's valid:

if (ptr && ptr->foo()) { ... }

That said, if what you really want is:

if (expr()) {
    fun();
}

just write that. The compiler will generate the same code either way, but the intent of what you're trying to do will be much clearer.

like image 65
Barry Avatar answered Mar 11 '26 19:03

Barry


  1. Yes it is legal. An expression followed by ; is a valid statement.

  2. Some folk might find it obfuscating.

  3. It cannot be optimised out if there are side effects.

Do be aware though that && can be overloaded in C++. If it's overloaded then then the short-cutting property of the operator is discarded. That will cause strange effects. It's chiefly for this reason that I would advise against this style.

like image 23
Bathsheba Avatar answered Mar 11 '26 17:03

Bathsheba



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!