Defining variables in control structures

2019-09-12 05:55发布

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())

2条回答
兄弟一词,经得起流年.
2楼-- · 2019-09-12 06:47

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
查看更多
太酷不给撩
3楼-- · 2019-09-12 06:57

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.

查看更多
登录 后发表回答