Possible Duplicate:
Why can't variables defined in a conditional be constructed with arguments?
Consider this simple example:
/*1*/ int main() {
/*2*/ for (int i(7); i;){break;}
/*3*/ if (int i(7)) {}
/*4*/ }
Why line-2 compiles just fine, whilst line-3 gives the error? This is little strange to me why if-statement is in this aspect treated worse than for-loop?
If this is compiler specific - I tested with gcc-4.5.1:
prog.cpp: In function 'int main()': prog.cpp:3:7: error: expected primary-expression before 'int' prog.cpp:3:7: error: expected ')' before 'int'
I was inspired by this question
[UPDATE]
I know this compiles just fine:
/*1*/ int main() {
/*2*/ for (int i = 7; i;){break;}
/*3*/ if (int i = 7) {}
/*4*/ }
[UPDATE2]
It seems to be purely academic question - but this could be extremely important for such types as std::unique_ptr<>
which cannot be copied:
#include <memory>
int main() {
if (std::unique_ptr<int> i = new (std::nothrow) int(7)) {
}
if (std::unique_ptr<int> i(new (std::nothrow) int(7))) {
}
}
Neither of these two kinds are allowed. Not sure about new C++11 syntax {}
?
The C++ standard doesn't provide a rationale but I would suspect that using the constructor notation could cause some inconsistencies. For example, since function declarations aren't allowed in the if
statement, the most vexing parse would actually mean what was intended. For example:
int f(); // function declaration (simple form or the most vexing parse)
if (int f()) { // illegal in C++ but, when allowed, would be a zero-initialized int
}
In C++ 2011 you can use brace-initialization:
if (int x{f()}) {
...
}
Unfortunately, brace-initialization doesn't always mean the same thing as using constructor notation (I think it's called direct-initialization).
With respect to the update: you can use one of these:
if (std::unique_ptr<int> p = std::unique_ptr<int>(new int(1))) { ... }
if (auto p = std::unique_ptr<int>(new int(2))) { ... }
if (std::unique_ptr<int>{new int(3)}) { ... }
It seems there are plenty of options :-)
In terms of syntax, the reason is simple.
The first element of the for
statement are statements. Statements can create variables as well as initialize them. The if
conditional is a condition. The spec does define that a condition can create a variable, but only by =
initialization.
Be glad the spec even allows you to create variables in an if
at all. It has to have special grammar to even allow that ("condition" being different from "expression"), and that was probably something inherited from C.
That being said, C++11 does define a condition as being able to initialize a declaration with a braced-init-list (spec-speak for "initializer list"). So it should be legal. But since VS2012 doesn't support initializer lists yet...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With