Where is the best place to declare variables? - c++

I am trying to optimize a program in C++ I have implemented and a question came in mind...
Where should I declare a variable if I have a repetitive structure using it?
For example:
//1-> int sum;
int matrix[10][10];
for(int i = 0; i < n; i++){
//1-> sum=0;
//2-> int sum=0;
for(int j = 0; j < n; j++)
sum += matrix[i][j];
printf("%d ", sum);
}
So which is better/recommended? Should I declare it at the beginning //->1 outside of the repetitive structure or it is fine if is redeclared //->2 at each iteration?
My guess is that declaration takes a very small time (milliseconds or less) but if you redeclare it in a repetitive structure big enough (or inside multiple structures) each redeclaration will add up to some extra seconds.

For an int it just doesn't matter. For a type with a non-trivial constructor or destructor, under scheme 2 it would be constructed and destroyed each time through the outer loop, and that would be potentially time-consuming.

It doesn't matter. The stack (reserved space in memory) is allocated all together in the beginning of the function/method. If it's an object, the contructor and destructor will be called somewhere in the scope of your loop. But for elemental types, there's absolutely no difference.

As others have already stated, it mostly doesn't matter for an int.
There are only two things to concern yourself with here:
Readability
Scope
If the int is declared right before the for loop rather than as the first line of the for loop, readability is probably about the same. Plus, many compiler's will have a shortcut for jumping straight to a declaration.
As for Scope, if you don't need the variable outside of the loop, putting it inside helps make sure you don't accidentally use it outside the loop in any way. If you do need it outside the loop, you really don't have much choice.
A note on my personal preference which combines both scope and readability issues, when I write code, I prefer having EVERY variable I will use in a given scope declared at the beginning of that scope. Any variable I use in main is declared at the top of main. Any variable used in a function is declared at the top of that function. Any variable used in a loop is declared at the top of that loop. Any variable used in a if statement is declared at the top of that if statement. I personally make very few exceptions. So in your case, if the scope of sum is limited purely to your for loop, I'd declare it as the first variable of the for loop. If sum needs scope outside of the loop, I'd declare it at the top of whatever function you're in and give it a far more descriptive name.

Related

cppcheck suggests to reduce scope of variable, should I?

So I have something like this
int age;
for (auto person : persons) {
age = std::stoi(person[0]);
/* Do other stuff with age in this loop*/
}
Other than style, are there any performance benefits to declaring int age = std::stoi(person[0]); inside the loop?
Since you have used the age variable only inside the for loop, you may reduce its scope and declare it inside the for loop only. That way, the compiler doesn't have to remember the variable once you're done with it in the loop.
You should declare it outside the loop only if you intend to use it outside as well.
are there any performance benefits
Because of the "as-if" rule, it's reasonable to assume that there is no performance difference between two equivalent ways of declaring the same variable.

Why declaring a variable inside a loop does not mean re declaring the variable each time loop is entered

int main()
{
int x;
int x;
return 0;
}
This snippet will give an error:
error: redeclaration of 'int x'
But this one, works just fine:
int main()
{
while(true)
{
int x;
{...}
}
return 0;
}
Which is the reason why in the second example, declaring x in the loop does not redeclare it every iteration? I was expecting the same error as in the first case.
You're smashing together two related but different concepts and thus your confusion. But it's not your fault, as most of the didactic material on the matter doesn't necessarily make the distinction between the two concepts clear.
Variable scope: This is the region of the source code where a symbol (a variable) is visible.
Object lifetime: this is the time during the runtime of the program that an object exists.
This brings us to other two concepts we need to understand and differentiate between:
A variable is a compile-time concept: it is a name (a symbol) that refers to objects
An object is an "entity" at runtime, an instance of a type.
Let's go back to your examples:
int main()
{
int x{};
int x{};
}
Here you try to declare 2 different variables inside the same scope. Those two variables would have the same name inside the function scope, so when you would "say" the name x (when you would write the symbol x) you wouldn't know to which variable you would refer. So it is not allowed.
int main()
{
while(true)
{
int x{};
}
}
Here you declare one variable inside the while body scope. When you write x inside this scope you refer to this variable. No ambiguity. No problems. Valid code. Note this discussion about declarations and variable scope applies at compile-time, i.e. we are discussion about what meaning has the code that you write.
When we discus object lifetime however we are talking about runtime, i.e. the moment when your compiled binary runs. Yes, at runtime, multiple objects will be created and destroyed in succession. All of these objects are referred by the symbol x inside the while body-scope. But the lifetimes of these objects don't overlap. I.e. when you run your program the first object is created. In the source code it is named x inside the while-body scope. Then the object is destroyed, the loop is re-entered and a new object is created. It is also named x in the source code inside the while-body scope. Then it is destroyed, the while is re-entered, a new object is created and so on.
To give you an expanded view on the matter, consider you can have:
A variable which never refers to an object
{ // not global scope
int a; // <-- not initialized
}
The variable a is not initialized, so an object will never be created at runtime.
An object without a name:
int get_int();
{
int sum = get_int() + get_int();
}
There are two objects returned by the two calls to the function get_int(). Those objects are temporaries. They are never named.
Multiple objects instantiated inside the scope of a variable.
This is an advanced, contrived example, at the fringe of C++. Just showing that it is technically possible:
{
int x;
// no object
new (&x) int{11}; // <-- 1st object created. It is is named `x`. Start of its lifetime
// 1st object is alive. Named x
x.~int(); // <-- 1st object destructed. End of its lifetime
// no object
new (&x) int{24}; // <-- 2nd object created. Also named `x`
// 2nd object alive. Named x
} // <-- implicit end of the lifetime of 2nd object.
The scope of x is the whole block delimited by the curly brackets. However there are two object with different non-overlapping lifetimes inside this scope.
Declarations don't happen at runtime, they happen at compile-time.
In your code int x; is declared once, because it appears in the code once. It doesn't matter if it's in a loop or not.
If the loop runs more than once, x will be created and then destroyed more than once. It's allowed, of course.
In c++, the curly braces represent the beginning {, and end }, of a scope. If you have a scope nested inside another scope, for example a while loop inside a function, then the previously declared variables from the outer scope are available inside the new loop scope.
You are not allowed to declare a variable with the same name inside the same scope twice. That's why the compiler creates the first error
error: redeclaration of 'int x'
But in the case of the loop, the variable is only declared once. It doesn't matter that the loop will reuse that declaration multiple times. Just like a function being called multiple times doesn't create a redeclaration error for the variables it declares.
Variables in loops stay in loops, and are not redeclared. This is because, to the best of my knowledge, Loops are just sets of instructions with jump points, and not actually the same code in the .exe file written over and over again.
If you try to make a for loop:
for(int x = 0; x < 10000; ++x);
The loop just reuses the same variable, then removes the variable after use. This is helpful so that loops, and do{}while(condition)'s can actally hold values, and not just have to redeclare, and reset each variable.
Back to the original question, I am going to ask my own: Why are you trying to redeclare a variable? You could just do this:
int main(void){
int variable = 0;
...
variable = 2;
}
Instead of this:
int main(void){
int variable = 0;
...
int variable = 2;
}
Curly brackets in C/C++ represent blocks of code. These blocks of code do not transfer information to other blocks. I recommend looking further into resources on blocks of code, but one resource has been linked here.
Unlike code that is written in "interpreted languages", variables require declaration. Moreover, your code is read sequentially in compiled languages.
Block example:
while (true) {
int i = 0;
}
This declaration is stored with the block somewhere in memory.
The storage is assigned to an "int" variable type. This data member has a certain memory capacity. Redeclaring, in essence, tries to override information stored in that particular block. These blocks are set aside at compilation time.

Defining variable outside of a loop [duplicate]

This question already has answers here:
Is there any overhead to declaring a variable within a loop? (C++) [duplicate]
(13 answers)
Closed 8 years ago.
Is there any performance difference between:
uint a;
for (uint i = 0 ; i < n ; ++i)
{
a = i;
}
and:
for (uint i = 0 ; i < n ; ++i)
{
uint a;
a = i;
}
Does the second piece of code result in a program creating a variable (allocating memory or sth) multiple times instead of just once? If not, is it because both codes are equivalent or because of some compiler optimization?
I expect all modern compilers to produce identical code in both cases.
You might be surprised to know that with most compilers there is absolutely no difference whatsoever in the amount of overhead between either case.
In brief, these kinds of variables are instantiated on the stack, and a compiler, for each function, computes the maximum amount of stack needed to instantiate all local variables inside the function, and allocate the required stack space at the function's entry point.
Of course, if instead of a simple int you have some class with a non-trivial amount of complexity in its constructor, then it would certainly make a lot of difference, in several ways. But for a simple int like this, absolutely nothing.
Assuming uint is a basic data type, I would say they are the same. Apart from the fact you can use a after the loop in the first example, of course. This is because the cost of placing basic data-types on the stack is trivial and the compiler can optimize this case so the memory is actually reserved once, as if you had declared it outside the loop.
If uint is a class, placing it outside the loop and reusing it could be faster. For example, declaring a std::string before a loop and reusing it inside the loop can be faster than creating a new string each iteration. This is because a string can reuse its existing dynamic memory allocation.
You can look at the disassembly of your compiler to see if there is any difference.
The second example must be slightly slower because a is being redefined for each iteration. This means that space is being set aside to store the maximum possible value of a (in this case, probably 4 bytes of memory). The allocation of that space is a command which will be executed, so I think that it is slower. Does it matter? Probably not.

CppCheck. The scope of the variable can be reduced (and loop)

CppCheck finds me some findings like: "The scope of the variable 'x' can be reduced".
What if I have this situation:
int x;
for (int i = 0; i != 10; ++i)
{
x = someFunction();
// ... I use x variable here
}
I think my code is OK. What do you think? Should it change to something like that?
for (int i = 0; i != 10; ++i)
{
int x = someFunction();
// ... I use x variable here
}
In the second code a variable x is defined for all iteration... Isn't not ok (not optimal), I guess..
The position of an int declaration has no performance impact, so Cppcheck is right when raising this style issue. This style issue can be applied to non-trivial types as well,
for (int i = 0; i != 10; ++i)
{
MyType x = someFunction();
// ... I use x variable here
}
since constructors tend to be as equally efficient as assignments. As of Version 1.65, Cppcheck seems not to distinguish between trivial and non-trivial types.
But don't blindly follow such style suggestions, there will be cases of non-trivial types where assignment is more efficient than construction. (As usual: if in doubt about performance, measure!)
Edit: a style consideration
The second variant is better in style as it combines declaration and initialization:
This often saves you from writing (or reading) a comment that is not very meaningful.
Sometimes you can also add const, which prevents you from accidental changes
If variable x is not used outside the loop then the second approach is much better. And there is not the slightest problem with the optimization of the code. The memory for the variable is allocated only once in the loop.
As others have mentioned, for trivial types it is unlikely to make significant performance impact.
However, you should also consider that, by reducing scope, you aid readability by having the declaration closer to usage, and possibly more importantly, make it easier to refactor.
Both of these could be important when considering maintainability.
We all know we should keep functions short and well refactored, but we have all seen those 5000 line long monsters, where a variable was declared at the top, and used once, 3789 lines in. And if you haven't, pity the rest of us.

Not able to underdtand this code...Is it C++11? [duplicate]

This question already has answers here:
Unnecessary curly braces in C++
(14 answers)
Closed 9 years ago.
I came across one project,where I found some code which I is not understandable to me. I just started with C++, so it seems like a big problem for me. I am providing few lines of my project,which I am not able to understand.
class abc
{
public:
//some stuff
abc();
};
abc::abc()
{
int someflag = 0;
//code
if(someflag == 0)
{
do
{
//few strcpy operations
{ //(My Question)Without any condition braces started
//variable initialization
}
}while(condition);
}
}
Now my questions...
What we can achieve by doing this operation?
What is happening in inside braces of do-while loop?
What is the scope of the initialized variables (I mentioned) inside
do-while loop?
Is it C++11?
Help me to understand this.
What we can achieve by doing this operation?
You introduce a scope block for the variables inside.
What is happening in inside braces of do-while loop?
See above.
What is the scope of the initialized variables (I mentioned) inside do-while loop?
The variables go out of scope at the end of the braces, they're there for that sole reason. One use case I can think of for this is a scoped_lock or something similar to it for multi-threaded applications.
Is it C++11?
No.
Even in C you can open a brace in any point where a statement is permitted.
This allows to declare and use new variables without interferring with the enclosing scope. For example:
... code before ...
{
int i = 0, sum = 0;
while (i < n) {
sum += dothis(data[i++]);
}
dothat(sum);
}
... code after ...
the two variables i and sum have nothing to do with variables with the same name in the enclosing scope: these two variables are created when entering the block and destroyed when exiting the block (while instead n and data are defined outside). This can help readability by avoiding separation between declaration and use or between declaration and initialization (in old C you were not allowed to put a variable declaration right before use... all locals were required to be declared at start of function: an annoying problem if you don't know yet the value to give them).
If you are in C++ and these block-local variables have a class type the constructor is called when entering the block (not when entering the function) and destroyed immediately when exiting the block. This can be very useful for example for locks
{
Lock mylock(resource);
use_resource();
}
Here are your answers:
Ans 1,2. This is used to define a new scope.
Ans 3. The scope of variables end as soon as the control moves out of the block
Ans 4. Probably the coder comes from C background and it is not particular to C++11 as in C, variables can only be declared at the beginning of a new scope.
Please look at THIS and THIS for further reference.
There are five types of scopes in C++
Function
File
Block
Function Prototype
Class
The code which you shared shows 'block scope'
Block scope
Blocks are portions of C++ code contained within curly braces( {....} ). Identifiers declared within a block have block scope and are visible from their points of definition to the end of the innermost containing block. A duplicate identifier name in a block hides the value of an identifier with the same name defined outside the block.
A variable name declared in a block is local to that block. It can be used only in it and the other blocks contained under it.