Uninitialized variable - passing it to a function - c++

http://en.cppreference.com/w/cpp/language/storage_duration
Static local variables
Static variables declared at block scope are initialized the first
time control passes through their declaration (unless their
initialization is zero- or constant-initialization, which can be
performed before the block is first entered). On all further calls,
the declaration is skipped.
What is the meaning of 'static' in this quote? Is it:
static storage duration. The storage for the object is allocated when
the program begins and deallocated when the program ends.
If so, then it doesn't explain what happens to int k; in the main or any other function in terms of initialization, because k is not a static variable (it doesn't get allocated when the program begins and deallocated when the program ends - wait a second, you might say that the main function starts running when the program begins and returns when the program ends, but that's not how it works I guess).
In the main function:
int k;
k++;
results in an error: uninitialized local variable 'k' used.
So if k above is not a static local variable, could you give an example of such variables?
And could anyone tell me why the following code compiles and runs without any issues, even though k is not initialized?
Given a function with no body:
void foo(int* number) { }
And calling it like this in main:
int k;
foo(&k);
k++;
It now compiles and runs with no problems, but the value of k is -858993459. The compiler didn't like the fact I attempted to increment it without initiation, but passing it to foo caused that the compiler forgot about it. Why?

Probably depends on your compiler implementation.
I guess the compiler sees that you variable is passed to a function in a non-const way, so the function can potentially modify/initialize the value of k.
Your compiler doesn't dig into the function to extrapolate the logic, so it let you compile the code.
EDIT : I don't get the same behaviour with this online compier : http://cpp.sh/9axqz
But the compilation warning disapears as soon as I do something with the number in the function.

A static local variable is something like this:
void example() {
static int i = 0; // a static local variable
int j = 0; // not static
// ...
}
Builtin types such as int are not automatically initialized. Therefore you may get a warning when you try to read from that variable before having set it to something meaningful because it can hold just about anything.
Just because your particular compiler no longer gave you a warning does not mean that your variable is initialized properly. As a rule of thumb you should always explicitly initialize your variables to avoid accidentally reading from it without having set it first:
int i; // not initialized
int j = 0; // explicitly set to 0
Here is a link to the C++ Core Guidelines on the topic of initialization: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es20-always-initialize-an-object, it may be worth a read.

A static variable can be defined like this:
int nextIndex()
{
static int index = -1;
return ++index;
}
So when you first call this function the static variable index will be initialized with -1;. The next line will increase index by 1 and return the result.
All subsequent calls of nextIndex will only execute the return ++index; part and skip the initialization.
Also static varibales are automatically initialized with zero if not implemented different.
So if you change above function to
int nextIndex()
{
static int index;
return ++index;
}
the first value it returns will be one. Also the first call won't initialize the index, but it will be initialized as soon as your program starts.

Related

Declaring a variable outside main function changes output even though there is only main function

So I have been working on a question and this think stumbled upon me. When I declare a variable outside the main function, the program works correctly, that is it reaches the else case of "Friendship is magic" but if the variable is declared inside it returns Chris instead of Friendship statement.
int mis, chr;
int main() {
int a, n, m;
cin >> a;
for (int i = 0; i < a; i++) {
//code here
}
if(mis > chr)
cout << "Mishka";
else if(chr > mis)
cout << "Chris";
else
cout << "Friendship is magic!^^";
}
The input that I am using makes the value of chr and mis equal so it should be evaluating to the else statement but instead it just stops at else if.
"With great power (provided by C++) there must also come great responsibility"
And
"With uninitialized variables comes the undefined behavior"
Variables that are declared at global scope are being initialized by the compiler. However, the variables defined inside any function (i.e, having automatic storage) may contain garbage values (that could be different in each invocation of the program). I recommend always initializing your variables to some value.
int main()
{
int mis = 0, chr = 0;
// ...
return 0;
}
Let's come to your program now:
When I declare a variable outside the main function, the program works correctly, that is it reaches the else case of "Friendship is magic"
It is happening because the variables (on which your if ladder dependent) are being initialized to 0. Since, both variables have same value (0), the else part of the if statement is being executed.
but if the variable is declared inside it returns Chris instead of Friendship statement.
It's a perfect example of undefined behavior. If they are defined inside your function, they will be holding some garbage value and that might not be equal. Hence, what you are observing is an undefined behavior and you might get different results in different machines or even sometimes in a same machine.
I tried your code and it works the same for me in both cases.
So, I would say it changes with editor to editor and always initialize the variable before using it.
Otherwise, we might face the same problem as you face. As it initializes the variables with garbage values.

Why the variables defined inside a for loop only exist inside of it?

I was reading C++ Primer by Stanley B. Lippman and at the part of flow control it shows an example of a for-loop like this one:
#include <iostream>
int main(void){
int sum=0;
for (int val=1; val <= 10; val++)
sum +=val;
std::cout << sum << std::endl;
return 0;
}
If I try std::cout << val; outside of the for-loop, the IDE gives me an error. But I want to understand why it happens and how it is different from this code:
#include <iostream>
int main(void){
int sum=0;
int val;
for ( val=1; val <= 10; val++)
sum +=val;
std::cout << sum << std::endl;
std::cout << val;
return 0;
}
Where I can actually print the val value without any problem.
Does it have something to do with local variable considering the for-loop a function that we are using inside of the main?
Every variable has scope, which is (loosely speaking) its lifetime.
A variable declared in the head of a for loop has scope limited to the for loop. When control passes out of the loop, the variable passes out of scope. Exactly the same thing happens to variables declared in a function, when control passes out of the function.
Does it have something to do with local variable considering the for-loop a function that we are using inside of the main?
Nothing to do with functions; there are plenty of other ways to get a scope, including a block:
int main()
{
{
int x = 0;
}
std::cout << x; // error
}
And a for loop is another example.
Its deliberate. Its called scope, Whenever you introduce a block { /*stuff here */ } (and a few other places) the variables inside the block are local to the block and supersede (hide) variables of the same name defined outside the block. It helps to ensure block-local code does not tread on other variables. Can be useful when editing an old codebase and you don't want to accidentally use a wider scoped variable.
The concept behind this is called Scope of the variable. Whenever a variable is created a memory location is assigned to it. So in order to optimize the memory usage scope of the variable is defined.
In the first case, the variable is limited only to the for loop. The variable is created inside at the beginning of the loop, utilized inside the loop and destroyed when the execution comes out of the loop.
In second case, the variable is created outside the loop so it persists till the execution of the program and hence you were able to access it even after the loop.
The variable declared inside the for loop is an example of local variable and that declared outside is an example of global variables.
Not only with the loops, the local variables will also be used in if..else blocks, functions and their usage is limited only within the scope.
Hope this answers your question.
Running this exact code does not turn up any errors for me. I get a value of 55 for sum and 11 for val as expected. Because you defined val outside of your for loop but in main, it should be good everywhere within the main() function to the best of my knowledge. As a general rule, if you declare a variable in between two curly braces without any fancy keywords, it should stay valid within those two curly braces (being "local" to that block of code). I am no c++ guru, so there might be exceptions to that (I am also not sure if "if" statements count as code blocks whose locally defined variables only work within the statement).

Declaring variables in C/C++

Someone told me: "declaring variables close to their use have value". He corrected me:
void student_score(size_t student_list_size) {
// int exam;
// int average;
// int digit;
// int counter_digits;
for (size_t i = 0; i < student_list_size; i++) {
int exam;
int average;
int digit;
int counter_digits;
I think it's bad, because here variables initialized every loop. What's true?
I encourage to declare them in as local a scope as possible, and as close to the first use as possible. This makes it easier for the reader to find the declaration and see what type the variable is and what it was initialized to. And of course, compiler will optimize it.
Both methods would be optimised to the same thing by the compiler. But for readability and ease of future maintenance, declaring the variables within the loop might be preferred by some.
I think it's bad, because here variables initialized every loop. What's true?
The code given the variables are not initialised at all.
So it is just a matter of personal taste.
It depends. C and C++ work differently in that regard. In C, variables MUST be declared at the start of its scope (forget that, it depends on your compiler although it holds true in pre-C99 compilers, as pointed out in the comments - thanks guys!), while in C++ you can declare them anywhere.
Now, it depends. Let's suppose the following two pieces of code:
int i = 0;
while (i < 5) {
i++;
}
while (i < 5) {
int i = 0;
i++;
}
In this case, the first piece of code is what's gonna work, because in the second case you declare the variable at each loop. But, let's suppose the following...
int i = 0;
while (i < 5) {
std::String str = "The number is now " + std::to_string(i);
cout << str << endl;
i++;
}
In short, declare the variables where it makes most sense to you and your code. Unless you're microoptimizing, like most things, it all depends on context.
This seems like a discussion with many personal opinions, so I'll add mine: I am a C programmer and like the C rules of having to declare your variables at the begining of a function (or block). For one thing, it tells me the stack lay-out so if I create another bug (I do "occassionaly") and overwrite something, I can determine the cause from just the stack lay-out. Then, when having to go through C++ code, I always have to search where the variable is declared. I rather look at the function beginning and see them all neatly declared.
I do ocassionally want to write for (int i=0;... and know the variable goes out of scope following the for loop (I hope it goes out of scope, as it is declared before the block begins).
Then there is an example in another answer:
while (i < 5) {
int i = 0;
i++;
}
and I hope it doesn't work because if it works it means there must be a variable i declared before this loop and so you have a clash of variables and scopes which can be horrible to debug (the loop will never terminate because the wrong i is incremented). I mean, I hope all variables must have been declared before their use.
I believe you must have a discipline in declaring your variables. The discipline can vary per person, just as long as it is easy to find where a variable is declared and what its scope is.
First of all that is not valid C code unless you are using -std=c99.
Furthermore, as long as you aren't creating dangling pointers in the loop, there is no problem with it.
The advantage you gain from doing it this way is that these variables are in a tight knit scope.
You need to know some knowledge of what local variable is ?
A variable declared inside a function is known as local variable. Local variables are also called automatic variables.
Scope: The area where a variable can be accessed is known as scope of variable.
Scope of local variable:
Local variable can be used only in the function in which it is declared.
Lifetime:
The time period for which a variable exists in the memory is known as lifetime of variable.
Lifetime of local variable:
Lifetime of local variables starts when control enters the function in which it is declared and it is destroyed when control exists from the function or block.
void student_score(size_t student_list_size) {
// int exam;
// int average;
// int digit;
// int counter_digits;
/* The above variable declared are local to the function student_score and can't be used
in other blocks. In your case its the for loop. */
for (size_t i = 0; i < student_list_size; i++) {
int exam;
int average;
int digit;
int counter_digits;
...
/* The above declared variable are local to the for loop and not to the function.*/
Consider this example:
#include<stdio.h>
void fun();
int main()
{
fun();
return 0;
}
void fun()
{
int i,temp=100,avg=200;
for (i=0;i<2;i++)
{
int temp,avg;
temp = 10 + 20;
avg = temp / 2;
printf("inside for loop: %d %d",temp,avg);
printf("\n");
}
printf("outside for loop: %d %d\n",temp,avg);
}
Output:
inside for loop: 30 15
inside for loop: 30 15
outside for loop: 100 200
If you are declaring the variable in loops the then declare the variable as static (In case if the value of the variable to be saved/used for further iteration).
Even compiler spend lot of time to initialize the variable in loops.
My suggestion is to declare at the beginning of the function. its a good programming practice.
I think, i made my point.

C++ bool not being initialized

Bellow is a simple program that is suppose to check a certain text file to see if a word, in this case a name, is present in it.
I keep getting a pop up stating "The variable 'NamePresent' is being used without being initialized." Isn't NamePresent initialized as a bool?
#include <fstream>
#include <iostream>
#include <string>
int main()
{
std::ifstream NameFile("Names.txt");
std::string Name;
bool NamePresent;
std::cin >> Name;
while(NameFile >> Name)
{
if(NamePresent == true)
{
std::cout << "This works!" << std::endl;
}
if(NamePresent == false)
{
std::cout << "Nope!" << std::endl;
}
}
return 0;
}
No, it is declared as a bool. You still need to assign it a value of either true/false:
bool NamePresent = false;
"Initialized" means initialized with a value.
bool NamePresent = false;
In your code above, it is declared as a bool, but not initialized. Also, no other statement in your code assigns a value to NamePresent (but presumably you're working on that).
Any decent compiler would give us the warning if program tries to use the variable which is not initialized(uninitialized).
test.cpp: In function ‘int main()’: test.cpp:15:9: warning:
‘NamePresent’ may be used uninitialized in this function
[-Wmaybe-uninitialized]
if(NamePresent == true)
^
You should pay attention to compiler messages carefully.
There are 4 important moments in the life of a variable:
Declaration
In this step you inform the compiler about the variable type. This is required so that the compiler knows how to interpret the data in memory, for example.
Definition
This is the "birth" of the variable. If in the declaration you specified its name and type, here you instruct the compiler to allocate memory for it. Note that a statement such as int a; is both a declaration and a definition, as it introduces a new name (a) and allocates memory for an int variable.
Initialization
When a variable is defined, some memory is reserved for it. The initial value of the variable is the content of that memory, which can be anything (this is usually known as garbage). So you need to assign the first useful value to your variable. Of course, you can use it without initialize it to a value, but this is error prone, as you cannot rely on the value of that variable. The compiler knows this and gives you a warning. Note that you will get also warnings if you initialize a variable in a loop or a conditional branch, as the condition might not be true or the loop might not be executed.
Death
Although this point has no real use for your question, it is worth remembering. A variable dies when it goes out of scope (usually when the instruction block where it has been defined ends, if it is a local variable, and when the program ends if it is a global variable).

Scope of variable

suppose
while(1)
{
{
{
int a=10;
a=5;
}
}
}
now as I cannot refer to "a" after its block's brace. I want to know when control moves up to first brace and then running down visited third brace again will "a" declared again or "a" hold value 5.
A new a variable will be defined in each step of loop.
a will only be declared when you declare it...
You declared it inside an inner scope, so any code referring to a will only be valid inside the same scope. Once you leave that scope, there exists nothing in your program called 'a' any longer. The memory that used to hold the value 5 may now be used by the rest of the program for other purposes.
Logically, the a cant be reference before its declaration, or after the close of the brace pair its declared in. It also gets destructed at the close, but thats a NOP for ints.
Each time around the loop it will be re-initialized to 10.
But, you missed the fun part of the question, about what happens if the declaration doesnt set the value:
while(1)
{
{
int a; // Here Scope Starts
a=5;
}// Here Scope Ends
}
Here, a will be undefined before it is set the first time. But, it will also almost always be in the same place on the stack, so it might possibly retain value from one iteration to the next, if nothing else uses that space. But whether or not it does can be execution dependant, which makes this an exciting source of bugs.
while(1)
{
{
{// Here Scope Starts
int a=10;
a=5;
}// Here Scope Ends
}
}
The variable will logically be reallocated on the stack with each iteration -- in practice, the memory location will simply be reused. But note, in your trivial example, the value of "a" would never "visibly" hold the value of "5" when the loop returns to the declaration on the next iteration because it is explicitly initialized to "10" at the point it is declared. And if C# follows the same practice as Java, it would be implicitly reinitialized to a default value at that point if the compiler does not complain first that an uninitialized variable is being accessed if you do not initialize it yourself.
each iteration of while loop , you will define new variable a and value of "a" change also but if you loop finish by any way you will lose this variable (you can't use it even in same function)!!
a will be declared again.
usually you will define parameter as a in the loop if you do want it to reset each loop so you won't carry values from iteration to iteration.
while(1)
{
{
{
//Define a new `a`
int a=10;
a=5;
}
}
}
But if you wish to use the same parameter and value for all the iterations, you need to define it out side the loop:
int a=0;
while(1)
{
{
{
//`a` will count the number of iterations.
a = a + 1;
}
}
}