Why is the following code illegal in C ++
I want to create if
where the variable is declared, assigned and checked. If the value of the variable is acceptable, I want to use it inside the body if
. Here's an example of how I thought I could do it:
if ((int result = Foo()) != 0) {
// use result
}
I assumed that it Foo()
returns some value, which is assigned result
and returned by the assignment operator =
, and finally checked against 0
in != 0
. Unfortunately this results in a compilation error:
main.cpp:31:10: error: expected primary-expression before ‘int’
if ((int i = Foo()) != 0)
^
main.cpp:31:10: error: expected ‘)’ before ‘int’
Why is this error happening? And what could fix it?
source to share
Your reasoning seems to be based on the assumption that =
in
if ((int result = Foo()) != 0)
is an assignment operator and which int result = Foo()
is "just an expression" that evaluates something.
This is not true.
The part is int result = Foo()
not an expression in C ++. This is an initializer declaration. The syntax =
in the initializer is not an assignment operator at all. It is simply a syntax element that coincidentally uses the same symbol as the assignment operator. int result = Foo()
is not an expression and does not "evaluate" any result.
Because if above, support for something like
if (int result = Foo())
requires special handling, which severely limits the flexibility of this syntax. What you have tried in your code is outside the scope of what is allowed by this special treatment.
source to share
The logic is supported, but declaring a variable in an expression if
and using it that way is not. The reason is that an initializer works differently than a regular assignment, but working around this is simple and trivial.
Just do something like this.
int result;
if ((result = Foo()) != 0) {
// use result
}
source to share
Bjarne uses this construction as a volume limiter in 6.3.2.1. C ++ programming language as a recommendation.
Using:
if (int result = Foo()) {
// use non-zero result
}
This is especially useful with pointers
if (Foo* result = GetFoo()) {
// use valid Foo
}
The part !=0
is redundant because the edit !=0
.
Extended construct with matching is not allowed.
Further discussion of this construct from here
source to share
It fails because it is illegal. This is ugly too. @Jonathan Wood suggested declaring the variable outside if
. I also suggest calling Foo
from outside:
int result = Foo();
if(result!=0) ...
The construct (x=f())!=y
, while legal as a condition if
, only makes sense in a loop where
`while ((c = GetChar ())! = '\ n) ... do something with c ...
Is the shorter and nicer equivalent
c = getchar();
while(c!='\n')
{
...
c = getchar(c);
}
Saves a record of calling getchar () twice. It doesn't save anything when used in if
, so there is no point in using it.
source to share