Reasons for putting C/C++ variables in an unnamed scope? [duplicate]
Asked Answered
C

6

6

Possible Duplicate:
Can I use blocks to manage scope of variables in C++?

I came across some C++ code that resembled:

int main(void) {

  int foo;
  float qux;
  /* do some stuff */

  {
    int bar;
    bar = foo * foo;
    qux = some_func(bar);
  }

  /* continue doing some more stuff */
}

Initially I thought that perhaps the original author was using braces to group some related variables, but being that the system under design doesn't have an abundance of memory I thought the author might have had the intention of having bar's scope resolve and any variables with in go away rather than have them around for the entire enclosing (foo's) scope.

Is there any reason to do this? It seems to me this shouldn't be necessary and that any modern compiler makes this unnecessary?

Cero answered 3/11, 2012 at 3:15 Comment(3)
Even if the compiler can optimize things, limiting scope as much as possible is good practice. Allows you to use the same variable name again later, for example. Useful for your is, js, and xs.Trask
@Thilo: If you're using things over and over, you need to split your function up! Also, for(int i; ...) already scopes i.Georgie
@Peter O., Kate Gregory: This is no duplicate. The other question asks specifically about memory consumption (object lifetime). There is not the right place to add other reasons for unnamed scopes which is asked here.Mcnully
J
10

It seems to me this shouldn't be necessary and that any modern compiler makes this unnecessary?

Yes, modern compilers will optimize the memory usage in cases like this. The extra scope won't make the code faster or more memory efficient.

However, they can't optimize objects with destructors with side-effects as that would change the behavior of the program. Thus, this makes sense to do for such objects.

Is there any reason to do this?

It is useful to group related code together. You know that variables declared inside the braces won't be used anywhere else which is extremely helpful to know.

Justinajustine answered 3/11, 2012 at 3:22 Comment(0)
T
4

If you do that multiple times in a single method, that could result in that method taking up less stack space, depending on your compiler. If you're resource limited, you might be on a microcontroller, and their compilers aren't always as full-featured as x86 compilers.

Also, if you do that with full classes (instead of ints & floats), it lets you control where the destructor is called.

class MyClass;

int main(void) {

    int foo;
    float qux;
    /* do some stuff */

    {
        MyClass bar;
        qux = some_func(bar);
    } // <-- ~MyClass() called here.

    /* continue doing some more stuff */
}
Thursday answered 3/11, 2012 at 3:23 Comment(0)
F
4

In case of C/C++ one can try to limit conflicts between names (having function that is so long that requires one to scope variable this way is bad idea...) i.e. if there are multiple bar in the same function than scoping them this way will let one make sure they don't collide/override each other.

Normally scope inside function does not impact stack allocation size - stack is pre-allocated for all local variables irrespective of scope.

Frederickson answered 3/11, 2012 at 3:24 Comment(0)
R
3

If the code is really like you've shown, it's probably pretty much pointless. Most compilers I've seen allocate the space for all local variables on entry to the function, and release it on exit from the function. There are a few other possibilities though.

If what you've shown as bar was an object of some class type (especially something with a destructor), the destructor would run on exit from the scope, even though the space wasn't released until later.

Another possibility is that there were really two inner scopes:

int main() { 
// ...

    { 
        // some variables
    }

// ...

    {
        // other variables
    }
}

In this case, the space for the local variables will be allocated on entry to main -- but, some variables and other variables will (typically) share the same space. I.e., the space that's allocated will be enough to accommodate the larger of the two, but will not (normally) be the sum of the two, as you'd use if you defined all the variables in main's scope.

Recursion answered 3/11, 2012 at 3:22 Comment(0)
N
2

intention of having bar's scope resolve and any variables with in go away rather than have them around for the entire enclosing (foo's) scope

This could be one (unimportant & legacy) reason.
The other reason is to convey it to the reader that int bar is just used within this scope to have a very small functionality (kind of function inside function). After that there is no use of bar.

Your code is equivalent of:

  inline void Update (int &foo, float &qux)
  {
    int bar = foo * foo;
    qux = some_func(bar);
  }
  int main ()
  {
    ...
    Update(foo, qux);
    ...
  }

Most compiler will optimize call to Update() inside main() and inline it, which generates similar to what you posted.

Northernmost answered 3/11, 2012 at 3:24 Comment(0)
R
2

It is likely meant to aid the programmer, not optimize the output, as a modern compiler is certainly smart enough to see a temporary variable is only used once.

On the other hand, for the programmer it adds a logical separation, it means "these variables are only needed for this code," and perhaps also "this code does not affect other code in this function."

Romilly answered 3/11, 2012 at 3:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.