Kiril Kirov
Kiril Kirov

Reputation: 38153

Defining a variable in the condition part of an if-statement does not allow comparison of its value. Why?

Summary

This question is related to: Defining a variable in the condition part of an if-statement?.

So, why I can't check the value of the newly defined variable in the same place?


Simple example

In other words, this is allowed (from the linked question):

if( int* x = new int( 20 ) ) 
{   
    std::cout << *x << "!\n";
    delete x;
}   

but this isn't:

if( NULL != ( int* x = new int( 20 ) ) )
{   
    std::cout << *x << "!\n";
    delete x;
}   

The second one gives me:

test.cpp:xx: error: expected primary-expression before ‘int’
test.cpp:xx: error: expected ‘)’ before ‘int’

Question

And (maybe) the more important question here - how is the condition of the first if evaluated? According to my tests, it seems like both options do the same - there's implicit check against false (0, NULL, whatever). But is it guaranteed by the standard?


Real-world example

OK, I can't check the new variable against some custom value, but I can compare it against false. So, here's a real-world example: I have a class, containing a template method: check_class. This method does a dynamic_cast of an internal pointer. Now I want to use it like:

if( some_class* some_class_ptr = cmd->check_class< some_class >() )
{
     // some_class_ptr is NOT NULL here
}
else if( other_class* other_class_ptr = cmd->check_class< other_class > )
{
    // other_class_ptr is NOT NULL here
}
// ...

The reason to want this is that the if will be pretty long and I don't want to declare all variables before it.

Upvotes: 1

Views: 187

Answers (3)

Mike Seymour
Mike Seymour

Reputation: 254431

So, why I can't check the value of the newly defined variable in the same place?

Because the syntax doesn't allow it. The condition can be either a declaration or an expression. An expression can't declare a named variable, and a declaration can't be used as an expression.

how is the condition of the first if evaluated?

The variable is initialised, and its value converted to bool. The condition succeeds if that yields true.

But is it guaranteed by the standard?

Yes:

C++11 6.4/3 The value of a condition that is an initialized declaration in a statement other than a switch statement is the value of the declared variable contextually converted to bool.

Upvotes: 3

The reason lies in the grammar of the language. In a nutshell, the code in the if condition (and similar constructs) can either be a declaration or an expression. When it's a declaration, there is of course no syntax to compare the declared entity to something.

When it's an expression, it's like any other expression anywhere else in code. Just as you cannot write this:

int foo() {
  bar(4 + (int b = 7));
}

you cannot put the same into an if.

Why it works with comparing against true is that when the code in the if is a declaration, the condition is evaluated as "the declared object contextually converted to bool."

Upvotes: 3

gx_
gx_

Reputation: 4760

how is the condition of the first if evaluated?

As you seem to think. The following

if( int* x = new int( 20 ) ) 
{   
    std::cout << *x << "!\n";
    delete x;
}   

is "roughly" equivalent to

{
   int* x = new int( 20 );
   if( x ) 
   {   
       std::cout << *x << "!\n";
       delete x;
   }   
}

and in the test if( x ) the expression x is implicitly converted to bool, which means if( x != 0 ) (or if( x != NULL )).

Upvotes: 0

Related Questions