According to the standard, what is the difference in behavior between declaring variables in control structures versus declaring variables elsewhere? I can't seem to find any mention of it.
If what I'm referring to isn't clear, here's an example:
if (std::shared_ptr<Object> obj = objWeakPtr.lock())
As you can see, I'm declaring and initializing a local variable, obj
, in the if block.
Also, is there any technical reason as to why this syntax isn't given any special behavior when used in place of a conditional? For example, adding an additional set of brackets results in a compiler error; this also prevents the variable from being chained with other conditions.
// Extra brackets, won't compile.
if ((std::shared_ptr<Object> obj = objWeakPtr.lock()))
// If the above were valid, something like this could be desirable.
if ((std::shared_ptr<Object> obj = objWeakPtr.lock()) && obj->someCondition())
According to the standard, what is the difference in behavior between declaring variables in control structures versus declaring variables elsewhere? I can't seem to find any mention of it.
Declarations inside control structure introductions are no different that declarations elsewhere. That's why you can't find any differences.
6.4/3 does describe some specific semantics for this, but there are no surprises:
[n3290: 6.4/3]:
A name introduced by a declaration in a condition
(either introduced by the type-specifier-seq or the declarator of the
condition) is in scope from its point of declaration until the end of
the substatements controlled by the condition. If the name is
re-declared in the outermost block of a substatement controlled by the
condition, the declaration that re-declares the name is ill-formed. [..]
Also, is there any technical reason as to why this syntax isn't given any special behavior when used in place of a conditional? For example, adding an additional set of brackets results in a compiler error; this also prevents the variable from being chained with other conditions.
An if
condition can contain either a declarative statement or an expression. No expression may contain a declarative statement, so you can't mix them either.
[n3290: 6.4/1]:
Selection statements choose one of several flows of control.
selection-statement:
if ( condition ) statement
if ( condition ) statement else statement
switch ( condition ) statement
condition:
expression
attribute-specifier-seq[opt] decl-specifier-seq declarator = initializer-clause
attribute-specifier-seq[opt] decl-specifier-seq declarator braced-init-list
It all just follows from the grammar productions.
The difference from declaring and initializing a variable in the condition and declaring it elsewhere is that the variable is used as the condition, and is in scope inside the if's conditional statement, but out of scope outside that condition. Also, it's not legal to re-declare the variable inside the if condition. So
bool x=something();
if(x) {
bool y=x; // legal, x in scope
int x=3; // legal
...
}
while (x=something_else()) // legal, x still in scope
...
but:
if(bool x=something())
bool y=x; // still legal
int x=3; // not legal to redeclare
...
}
while (x=something_else()) // x declared in condition not in scope any more