Reputation: 38153
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
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 tobool
.
Upvotes: 3
Reputation: 171117
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
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