C++, variable declaration in 'if' expression
I think you already hinted at the issue. What should the compiler do with this code?
if (!((1 == 0) && (bool a = false))) {
// what is "a" initialized to?
The "&&" operator is a short-circuit logical AND. That means that if the first part (1==0)
turns out to be false, then the second part (bool a = false)
should be not be evaluated because it is already known that the final answer will be false. If (bool a = false)
isn't evaluated, then what to do with code later on that uses a
? Would we just not initialize the variable and leave it undefined? Would we initialize it to the default? What if the data type was a class and doing this had undesirable side effects? What if instead of bool
you used a class and it had no default constructor such that the user must provide parameters - what do we do then?
Here's another example:
class Test {
public:
// note that no default constructor is provided and user MUST
// provide some value for parameter "p"
Test(int p);
}
if (!((1 == 0) && (Test a = Test(5)))) {
// now what do we do?! what is "a" set to?
Seems like the limitation you have found seems perfectly reasonable - it prevents these kinds of ambiguities from happening.
As of C++17 what you were trying to do is finally possible:
if (int a = Func1(), b = Func2(); a && b)
{
// Do stuff with a and b.
}
Note the use of ;
of instead of ,
to separate the declaration and the actual condition.
The condition in an if
or while
statement can be either an expression, or a single variable declaration (with initialisation).
Your second and third examples are neither valid expressions, nor valid declarations, since a declaration can't form part of an expression. While it would be useful to be able to write code like your third example, it would require a significant change to the language syntax.
I don't see where it says anything about not being able to put parenthesis around the declaration, nor does it say anything about only one declaration per condition.
The syntax specification in 6.4/1 gives the following for the condition:
condition:
expression
type-specifier-seq declarator = assignment-expression
specifying a single declaration, with no parentheses or other adornments.