Reasons for putting C/C++ variables in an unnamed scope? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
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?

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.

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 */
}

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.

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.

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.

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."

Related

Static data memory limit in C++ application

Someone has written function in our C++ application and is already in the production and I don't know why it's not crashing the application yet. Below is the code.
char *str_Modify()
{
char buffer[70000] = { 0 };
char targetString[70000] = { 0 };
memset(targetString, '\0', sizeof(targetString));
...
...
...
return targetString;
}
As you can see, the function is returning the address of a local variable and the allocated memory will be released once the function returns.
My question
Wanted to know what is the static data memory limit?
What can be the quick fix for this code? Is it a good practice to make the variable targetString static?
(Note that your call to memset has no effect, all the elements are zero-initialised prior to the call.)
It's not crashing the application since one manifestation of the undefined behaviour of your code (returning back a pointer to a now out-of-scope variable with automatic storage duration) is not crashing the application.
Yes, making it static does validate the pointer, but can create other issues centred around concurrent access.
And pick your language: In C++ there are other techniques.
Returning targetString is indeed UB as other answers have said. But there's another supplemental reason why it might crash on some platforms (especially embedded ones): Stack size. The stack segment, where auto variables usually live, is often limited to a few kilobytes; 64K may be common. Two 70K arrays might not be safe to use.
Making targetString static fixes both problems and is an unalloyed improvement IMO; but might still be problematic if the code is used re-entrantly from multiple threads. In some circumstances it could also be considered an inefficent use of memory.
An alternative approach might be to allocate the return buffer dynamically, return the pointer, and have the calling code free it when no longer required.
As for why might it not crash: if the stack segment is large enough and no other function uses enough of it to overwrite buffer[] and that gets pushed first; then targetString[] might survive unscathed, hanging just below the used stack, effectively in a world of its own. Very unsafe though!
It is well defined behaviour in C and C++ because return an address of a static variable exist in memory after function call is over.
For example:
#include <stdio.h>
int *f()
{
static int a[10]={0};
return a;
}
int main()
{
f();
return 0;
}
It is working fine on GCC compiler. [Live Demo]
But, if you remove static keyword then compiler generates warning:
prog.c: In function 'f':
prog.c:6:12: warning: function returns address of local variable [-Wreturn-local-addr]
return a;
^
Also, see this question comments wrote by Ludin.
I believe you are confusing this with int* fun (void) { static int i
= 10; return &i; } versus int* fun (void) { int i = 10; return &i; }, which is another story. The former is well-defined, the latter is
undefined behavior.
Also, tutorialspoint say's :
Second point to remember is that C does not advocate to return the
address of a local variable to outside of the function, so you would
have to define the local variable as static variable.
Wanted to know what is the static data memory limit?
Platform-specific. You haven't specified a platform (OS, compiler, version), so no-one can possibly tell you. It's probably fine though.
What can be the quick fix for this code?
The quick fix is indeed to make the buffer static.
The good fix is to rewrite the function as
char *modify(char *out, size_t outsz) {
// ...
return out;
}
(returning the input is just to simplify reusing the new function in existing code).
Is it a good practice to make the variable targetString static?
No. Sometimes it's the best you can do, but it has a number of problems:
The buffer is always the same size, and always using ~68Kb of memory and/or address space for no good reason. You can't use a bigger one in some contexts, and a smaller one in others. If you really have to memset the whole thing, this incurs a speed penalty in situations where the buffer could be much smaller.
Using static (or global) variables breaks re-entrancy. Simple example: code like
printf("%s,%s\n", str_Modify(1), str_Modify(2));
cannot work sanely, because the second invocation overwrites the first (compare strtok, which can't be used to interleave the tokenizing of two different strings, because it has persistent state).
Since it isn't re-entrant, it also isn't thread-safe, in case you use multiple threads. It's a mess.

Some basic C++ concepts — initialization and assignment

I was asked in an interview, to tell the exact difference for the following c/c++ code statements
int a = 10;
and
int a;
a = 10;
Though both assign the same value, they told me there is a lot of difference between the two in memory.
Can anyone please explain to me about this?
As far as language concerned, they are two ways to do the same thing, initialize the variable a and assign 10 to it.
The statement
int a; reserves memory for the value a which certainly contains garbage.
Because of that you initialize it with a = 10;
In the statement int a = 10; these two steps are done in the same statement.
First a part of memory is reserved to the variable a, and then the memory is overwritten with the value of 10.
int a = 10;
^^^^^ ^^^^^
reserve memory for the variable a write 10 to that memory location
Regarding memory the first declaration uses less memory on your PC because less characters are used, so your .c file will be smaller.
But after compilation the produced executable files will be the same.
IMPORTANT: if those statements are outside any function they are possibly not the same (although they will produce the same result).
The problem is that the first statement will assign 0 to a in the first statement because most compilers do that to global variables in C (and is defined by C standard).
"Though both assign the same value, but there is a lot of difference between the two in memory."
No, there's no difference in stack memory usage!
The difference is that assigning a value though initialization may cause some extra cost for additional assembler instructions (and thus memory needed to store it, aka. code footprint), the compiler can't optimize out at this point (because it's demanded).
If you initialize a immediately this will have some cost in code. You might want to delay initialization for later use, when the value of a is actually needed:
void foo(int x) {
int a; // int a = 30; may generate unwanted extra assembler instructions!
switch(x) {
case 0:
a = 10;
break;
case 1:
a = 20;
break;
default:
return;
}
// Do something with a correctly initialized a
}
This could have well been an interview question made to you in our company, by particular colleagues of mine. And they'd wanted you to answer, that just having the declaration for int a; in 1st place is the more efficient choice.
I'd say this interview question was made to see, if you're really have an in-depth understanding of c and c++ language (A mean-spirited though!).
Speaking for me personally, I'm more convenient on interviews about such stuff usually.
I consider the effect is just very minimal. Though it could well seriously matter on embedded MCU targets, where you have very limited space left for the code footprint (say less/equal than 256K), and/or need to use compiler toolchains that actually aren't able to optimize this out for themselves.
If you are talking about a global variable (one that doesn't appear in a block of code, but outside of all functions/methods):
int a;
makes a zero-initialized variable. Some (most?) c++ implementations will place this variable in a memory place (segment? section? whatever it is called) dedicated for zero-initialized variables.
int a = 10;
makes a variable initialized to something other than 0. Some implementations have a different region in memory for these. So this variable may have an address (&a) that is very different from the previous case.
This is, I guess, what you mean by "lot of difference between the two in memory".
Practically, this can affect your program if it has severe bugs (memory overruns) - they may get masked if a is defined in one manner or the other.
P.S. To make it clear, I am only talking about global variables here. So if your code is like int main() {int a; a = 10;} - here a is typically allocated on stack and there is no "difference in memory" between initialization and assignment.

Why doesn't the compiler know the addresses of local variables at compile-time?

What does the following statement mean?
Local and dynamically allocated variables have addresses that are not known by the compiler when the source file is compiled
I used to think that local variables are allocated addresses at compile time, but this address can change when it will go out of scope and then come in scope again during function calling. But the above statement says addresess of local variables are not known by the compiler. Then how are local variables allocated? Why can global variables' addresses be known at compile time??
Also, can you please provide a good link to read how local variables and other are allocated?
Thanks in advance!
The above quote is correct - the compiler typically doesn't know the address of local variables at compile-time. That said, the compiler probably knows the offset from the base of the stack frame at which a local variable will be located, but depending on the depth of the call stack, that might translate into a different address at runtime. As an example, consider this recursive code (which, by the way, is not by any means good code!):
int Factorial(int num) {
int result;
if (num == 0)
result = 1;
else
result = num * Factorial(num - 1);
return result;
}
Depending on the parameter num, this code might end up making several recursive calls, so there will be several copies of result in memory, each holding a different value. Consequently, the compiler can't know where they all will go. However, each instance of result will probably be offset the same amount from the base of the stack frame containing each Factorial invocation, though in theory the compiler might do other things like optimizing this code so that there is only one copy of result.
Typically, compilers allocate local variables by maintaining a model of the stack frame and tracking where the next free location in the stack frame is. That way, local variables can be allocated relative to the start of the stack frame, and when the function is called that relative address can be used, in conjunction with the stack address, to look up the location of that variable in the particular stack frame.
Global variables, on the other hand, can have their addresses known at compile-time. They differ from locals primarily in that there is always one copy of a global variable in a program. Local variables might exist 0 or more times depending on how execution goes. As a result of the fact that there is one unique copy of the global, the compiler can hardcode an address in for it.
As for further reading, if you'd like a fairly in-depth treatment of how a compiler can lay out variables, you may want to pick up a copy of Compilers: Principles, Techniques, and Tools, Second Edition by Aho, Lam, Sethi, and Ullman. Although much of this book concerns other compiler construction techniques, a large section of the book is dedicated to implementing code generation and the optimizations that can be used to improve generated code.
Hope this helps!
In my opinion the statement is not talking about runtime access to variables or scoping, but is trying to say something subtler.
The key here is that its "local and dynamically allocated" and "compile time".
I believe what the statement is saying is that those addresses can not be used as compile time constants. This is in contrast to the address of statically allocated variables, which can be used as compile time constants. One example of this is in templates:
template<int *>
class Klass
{
};
int x;
//OK as it uses address of a static variable;
Klass<&::x> x_klass;
int main()
{
int y;
Klass<&y> y_klass; //NOT OK since y is local.
}
It seems there are some additional constraints on templates that don't allow this to compile:
int main()
{
static int y;
Klass<&y> y_klass;
}
However other contexts that use compile time constants may be able to use &y.
And similarly I'd expect this to be invalid:
static int * p;
int main()
{
p = new int();
Klass<p> p_klass;
}
Since p's data is now dynamically allocated (even though p is static).
Address of dynamic variables are not known for the expected reason,
as they are allocated dynamically from memory pool.
Address of local variables are not known, because they reside on
"stack" memory region. Stack winding-unwinding of a program may
defer based on runtime conditions of the code flow.
For example:
void bar(); // forward declare
void foo ()
{
int i; // 'i' comes before 'j'
bar();
}
void bar ()
{
int j; // 'j' comes before 'i'
foo();
}
int main ()
{
if(...)
foo();
else
bar();
}
The if condition can be true or false and the result is known only at runtime. Based on that int i or int j would take place at appropriate offset on stack.
It's a nice question.
While executing the code, program is loaded into memory. Then the local variable gets the address. At compile time, source code is converted into machine language code so that it can be executed

Calling operator new at global scope

A colleague and I were arguing the compilability of writing this at global scope:
int* g_pMyInt = new int;
My arguments revolved around the fact that calling a function (which new is)
at global scope was impossible. To my surprise, the above line compiled just fine
(MS-VC8 & Apple's LLVM 3).
So I went on and tried:
int* foo()
{
return new int;
}
int* g_pMyInt = foo(); // Still global scope.
And, that compiled as well and worked like a charm (tested later with a class
whos constructor/destructor printed out a message. The ctor's message
went through, the dtor's didn't. Less surprised that time.)
While this appears very wrong to me (no orderly/right way/time to call delete),
it's not prohibited by the compiler. Why?
Why shouldn't it be allowed? All you're doing is initializing a global variable, which you are perfectly welcome to do, even if the initialization involves a function call:
int i = 5 + 6;
double j(std::sin(1.25));
const Foo k = get_my_foo_on(i, 11, true);
std::ostream & os(std::cout << "hello world\n");
int * p(new int); // fine but very last-century
std::unique_ptr<int> q(new int); // ah, welcome to the real world
int main() { /* ... */ }
Of course you'll need to worry about deleting dynamically allocated objects, whether they were allocated at global scope or not... a resource-owning wrapper class such as unique_ptr would be the ideal solution.
C++ allow processing to happen before and after the main function, in particular for static objects with constructors & destructors (their constructor have to run before main, their destructor after it). And indeed, the execution order is not well defined.
If you are using GCC, see also its constructor function attribute (which may help to give an order).
Of course you can call functions from global scope, as part of the initialization of global objects. If you couldn't, you couldn't define global variables of types with constructors, because constructors also are functions. However be aware that the initialization order between different translation units is not well defined, so if your function relies on a global variable from another translation unit, you will be in trouble unless you took special precaution.

Local-variable declaration inside a "virtual" loop optimization

This time, I couldn't find what I'm looking for (dunno if I'm not searching for the right stuff...) but, here it is:
In c++, imagine you have a function Bar() that is called once every cycle... like this:
class Foo {
public:
void Bar() {
double my_array[3];
// fills the array based on some calculations
double my_array1[3];
// fills the array based on some calculations
double my_array2[3];
// fills the array based on some calculations
_member_of_class = my_array + my_array1 + my_array2; //+ overloaded
}
private:
float _member_of_class[3];
}
int main(int argc, char** argv) {
Foo foo;
while(/*program running*/) {
foo.Bar();
//LOTS of code here
}
return 0;
}
Now, my_arrays are temporary arrays, not important to be data members, just used to fill the class member... Obviously, the overhead of calling that function is not necessary... Is there a way (well, I'm trying to avoid putting them as class members) of telling the compiler to "save the allocation space" or something so they is less overhead? const would give any tip to the compiler? I'm not sure I'm being clear...
Anyway, thanks!
Use a profiler
As it stands, the function is declared inline in a class. This code will trivially optimize, and the compiler will probably get the allocations out of the loop anyway (depending on how much cruft you have left out of the picture, really).
Also, the overloaded array operators likely get vectorized in gcc (starting with -O3 of -ftree-vectorize). Just look at the verbose out put with
g++ -O3 -march-native -ftreevectorizer-verbose=2 ...
to see what loops got vectorized, and if not, why not.
By all means have a look at the output of g++ -S etc.
Use a profiler. Don't 'optimize' if you don't know that it's necessary.
Pass them as parameters to the Bar function. Arrays decay into pointers and will be quite fast to pass.
You can declare the arrays as static. This will force the compiler to reserve some memory for them, rather than putting them on the stack each time you call the function. Keep in mind that this breaks thread-safety, however.
Also remember that the stack is pre-allocated; this code isn't actually allocating any new memory for your arrays, it's only placing them in memory that's already allocated. There is no overhead here. Your compiler can reserve space for all three arrays with only one instruction.
Why not consider making the arrays private members? If you want to guarantee no overhead in stack allocation during runtime making them private members would make it clear to other programmers that that is what was happening , where as compiler switches or relying on optimisations automatically done by the compiler aren't always obvious to other devs.