Why would the variable n become undefined in the below if statement when it is a global variable?
function aisaRev() {
n=n; //globally n=0
console.log(n);
hover=1;
rev=2;
//n counts up to 39 and then becomes undefined when it hits the else statement
if (n<=aisaArray.length){n++}else{n=0; console.log(n)};
world();
}
nevermind
should have been
if (n<aisaArray.length -1){n++}else{n=0; console.log(n)};
something else was becoming undefined before it hit the else statement
Related
I know there are plenty of answers out there but non of them cleared my doubt...
C++ standard says:
The for statement
for ( init-statement condition ; expression ) statement
is equivalent to
{
init-statement
while ( condition ) {
statement
expression ;
}
}
except that names declared in the init-statement are in the same declarative-region as those >declared in the condition (which is also the scope of statement).
It means if I declare a variable inside the init-statement, then that variable will be in the same scope as that of statement and the statement executes in each iteration...
now, my question is:
Does variable declaration in init-statement also executed in each iteration?
for eg:
for(int i = 0; i < 5; i++){
int number = 2; // this will be executed in each iteration
}
Now, as standard says 'i' variable will also be in the same scope of 'number' so does it also destroyed and declared at each iteration like 'number'?
PS: but it can't be because standards also says that init statement executes one and only once before the condition statement.. I just want to know the reason and how things work?
EDITED
for(int i=0; i<10; i++){
int num = 2;
}
acc. to the standards The 'i' variable and the 'num' variable both are in the same scope then how 'i' variable is declared only once and num variable declared repeatedly (here 10 times), I mean if they both are in the same scope isn't 'i' variable too destroyed and declared 10 times like 'num'...(I know it may sound silly but it is confusing me a lot)
The exception is mostly to pinpoint that
for (int i = 0; i != 42; ++i)
{
int i = 3; // error: redeclaration of i
}
whereas
{
int i = 0;
while (i != 42) {
int i = 3; // "Ok", hide outer i
++i; // actually modify inner i
}
}
That doesn't affect lifetime of variable or place of initialization.
As standard says, i will be in same scope as number, but if you have a look at the code that standard provides, i will be initialized only once. number, on the other hand, will be initialized in each iteration.
See the equivalent while loop. Variable declared in the initiator outlives all instances of variables inside the loop. But once the for loop ends, the initial variable gets out of scope and dies(gets destructed).
One thing to note is if can also define variables in condition part:
if(bool x=foo()) /*...*/;
if(int x=bar(); x>3) /*...*/;
and similar rule applies; You'll get an implicit scope around if/while statement. But there is difference between while and for.In contrast to for, the object initiated inside a while condition:
while(bool x=foo()) /*...*/;
is actually scoped inside the loop and gets destructed/constructed per iteration
Mind the term scope. Roughly speaking, Scope is any pair of curly braces ({}) that forms a block statement. But there are implicit scopes too - just like the ones around for/while/if. Any scope that gets exited, kills its nested objects.
regards,
FM.
Below is my code in C++. Here in the function "temp", 1st, the value of 'ch' is declared & then printed(at the first time 'ch' is not initialized so 'ch' has Undefined value).Then "if" condition is satisfied(Inside "if" no work is done). Then function gets over & returned to the next line of the function call(increments 'i'). Then the next iteration also goes in the same way as the previous call. The same cycle goes on until a key is pressed. When a key is pressed(for e.g. 'a' is pressed), "else" gets executed & the key pressed is taken by getch(). Then function gets over & returned to next line of function call(i++), then in all the coming next iteration, when a function is called, 'ch' is assigned with the previous key pressed('a') and it prints that character('a'). It goes on printing 'a' until another key is pressed. Why & how 'ch' is assigned with the previous function call's value. Is the value of variable of previous call is stored inside the stack & assign it to the next call's variable?
#include<iostream>
#include<conio.h>
#include<stdlib.h>
using namespace std;
int flag = 0,i = 1;
void temp()
{
char ch;
cout<<ch;
if(!_kbhit())
{
}
else{
ch=_getch();
}
}
int main()
{
while(flag!=1)
{
temp();
i++;
}
return 0;
}
In your code (and on Intel), after calling temp() and it returned, there is no code that modifies the location of ch on the stack. As a consequence it still has the previous value when you call it again.
Would you call for example printf() in main() after calling temp(), then this call would overwrite the location of ch.
To answer your specific question, you are just getting lucky.
C++ doesn't clear out memory unnecessarily. When you call temp() for a second or subsequent time, in this case it it allocates memory in exactly the same way as the previous time, and so you see the same value in ch.
However, any slight change to you programme structure or to your compiler settings could mean that the memory layout was not aligned and you wouldn't get this behaviour.
As suggested in the comments, changing the declaration to
static char ch;
would guarantee that the value was preserved between calls, at a potential very slight cost to memory and performance.
"Why and how ch is assigned with the previous function call's value?"
"Is the value of the variable ch of the previous call stored inside the stack and assigned to ch in the next call to temp()?"
In C++, function-local objects do not need to be destroyed after the function has returned, which seems to be in your case.
Nonetheless the behavior is undefined . What you trying to understand is based upon undefined results of your execution.
Since ch is not initialized, printing its value could output any value.
That it prints the character 'a' at all other function calls to temp() is a sign of undefined behavior.
You can find a well-defined solution for this by qualifying the variable ch with the static storage-class specifier which means the variable ch is stored in the BSS segement of your executable, F.e.:
static char ch;
Then ch keeps alive in the stack memory even between function calls with its value.
This furthermore also has the beneficial side effect, that ch is automatically 0 initialized. Thus, no undefined behavior anymore.
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.
#include<iostream>
using namespace std;
void test(int *s){
s++;
*s=3;
}
int main(){
int s=0;
test(&s);
cout<<s;
return 0;
}
The output I am getting 000. I was expecting only 0. But I am getting zeros equal to value assigned to s in test function. I am not able to understand why is it giving this output?
Edited.
Undefined behaviour is undefined. When called like in your main, test writes through an invalid pointer, so anything can happen.
Your program has undefined behavior.
The line
s++;
increments the pointer, not the value of the object the pointer points to.
and then the line
*s=3;
modified the value at of the new location the pointer points to. That is accessing memory that you are not supposed to access.
You passed &s in test function argument so the *s is the actual value but when you incremented s the pointer went to an undefined location and hence the output could be anything. remove the line s++ and you will get 3 as answer.
Iam trying to compile this program but i get warning and when i run vc++ 2010 debugger pops up : (
Here is my code :
#include <iostream>
using namespace std;
int num;
int min(int mas[])
{
int i,minn,index; /* But I have declared them : (((( */
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
if(i==num) return 0;
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
mas[index]=0;
return minn;
}
int main()
{
cin>>num;
int *array=new int[num]; int tmp;
tmp=min(array);
}
and Here is a compiler log :
prog.cpp: In function ‘int min(int*)’:
prog.cpp:6: warning: ‘index’ may be used uninitialized in this function
prog.cpp:6: warning: ‘minn’ may be used uninitialized in this function
What i am doing wrong ? or its is compiler bug ? :)
Thank you :)
You have declared them, but not initialized them. Simply write int minn = 0, index = 0; to avoid the warning. If you don't initialize a variable, its default value is whatever was at that location in memory already; usually garbage.
The thing is, if num is negative, then neither of the for loops in your min() function will execute, and so minn and index will not have been assigned values. The if(i == num) test also won't break out of the function and prevent this from happening. So the last two lines of the function will have completely undefined results.
Sometimes there really isn't a path for the variables to be used uninitialized, though; sometimes the compiler just isn't quite smart enough to figure out all the subtleties. Just give them an initial value to avoid the warning.
Declaration != initialization. When you declare them the variables have random values. Just initialize them to sensible values like -1 for index and minn to a INT_MAX.
But you haven't initialized them : ))))
EX: int i,minn=0,index=0; Imagine that you pass num that equals 0, at the end you would be returning uninitialized value of minn and just before that you would set mas[unknown_number]=0; which will probably cause your app to crash since you will be referencing memory that is most likely beyond your scope. You should do a check in the beggining like if(num<1)return -1;
Suppose the entire array you pass in is 0. Both loops short-circuit and never execute, both minn and index are uninitialized.
Now if this happens, what should be happening? Set the variables to the values that accomplish just that.
As you say in your comment, yes, you have declared your variables, but you haven't initialized them. Initializing a variable means giving it a value. So in this case, you have told the compiler that you want to create three integers, but you haven't told it what values you want to store in those integers. That would be ok if, for every possible path through your function, index and minn were guaranteed to be given a value, but the problem here is that there is a path through your function where minn and index will never be initialized. First of all, here:
for(i=0;i<num;i++)
{
if(mas[i]!=0)minn=mas[i];
break;
}
If you have an array of zeros, then minn is never initialized to a value.
Then further down:
for(i=0;i<num;i++)
if(mas[i]!=0 && minn>mas[i])
{
minn=mas[i];
index=i;
}
first of all, if you had an array of zeros, well what is the value in minn? There is no value. You are asking the compiler to compare mas[i] to a number which doesn't exist. Furthermore, what if mas[i] is always equal to zero? Well now you don't initialize minn or index. Yet at the end of the function, you are attempting to use the value of index to get an integer from the array amd then you return minn (which still equals nothing).
That's the problem you're getting from the compiler. It can see this potential outcome and is warning you that your function can be broken due to these integers never getting a value. To fix it, do what the other lads have suggested and let index and minn equal zero at the start.