#include<stdio.h>
int main(){
int a=10;
{ printf("%d",a);
int a=20;
printf("%d",a);
}
printf(" %d",a);
return 0;
}
Output:10 20 10
In the above code I understand that the visibility of variable a(inside inner block) has scope only within that block therefore I get that particular output.
But the variable a which is declared outside that block should have its scope even within the inner block...Therefore how is it possible for me to again type int a=20;
Shouldn't it give me an error like "redefinition of a" and "previous declaration of a was here". Like if I use
int b=10;
int b=15;
My second problem is this
void main() {
static int a=10;
{
printf("%d ",a);
static int a=20;
printf("%d",a);
}
printf(" %d",a);
}
Apart from the same doubt as the previous code about why I'm not getting an error like "redefinition of a", This is my doubt related to this code.
For the above code i get the same Output: 10 20 10 but what I was expecting was
10 20 20
I mean in the inner block once static int a is reinitialized to 20 shouldn't it be the same value even after it exits the block? because the a static variable's scope is throughout the entire program.
Answer for the first problem: It is called variable shadowing. From Wikipedia:
variable shadowing occurs when a variable declared within a certain
scope (decision block, method, or inner class) has the same name as a
variable declared in an outer scope.
Simply put, when you create a variable with the same name but in other scope it shadows the previous variable.
About the second problem - here is a fine example:
// static1.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
void showstat( int curr ) {
static int nStatic; // Value of nStatic is retained
// between each function call
nStatic += curr;
cout << "nStatic is " << nStatic << endl;
}
int main() {
for ( int i = 0; i < 5; i++ )
showstat( i );
}
Output:
nStatic is 0
nStatic is 1
nStatic is 3
nStatic is 6
nStatic is 10
#include<stdio.h>
int main(){
int a=10;
{ printf("%d",a);
int a=20;
printf("%d",a);
}
printf(" %d",a);
return 0;
}
The second a is in a different scope, as you seem to already understand. The "redefinition of a" error only applies when you define two variables with the same name in the same scope.
void main() {
static int a=10;
{
printf("%d ",a);
static int a=20;
printf("%d",a);
}
printf(" %d",a);
}
Again, the a inside the inner block only has scope within that block. If you re-enter the same block, a will continue to have the same value because you declared it as static. However, outside of the block, you will use the value of first variable a. This illustrates the difference between a variable's scope and its lifetime.
Related
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<::x; // should print 10;
}
return 0;
}
Is there any way to print x=10 without changing variable names, variable values and position of cout?
I assume this is an academic question (puzzle) because nobody should write code like that. In the same spirit, here's a way to make it print 10 instead of 15 without changing variable names, variable values and the position of cout:
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
#define x x-5
cout<<::x; // should print 10;
}
return 0;
}
Normally you should parenthesize such expressions in macros, like (x-5). In this case, that would be counterproductive :)
No you can't
An inner block, because it is a different block, can re-utilize a name existing in an outer scope to refer to a different entity; in this case, the name will refer to a different entity only within the inner block, hiding the entity it names outside.
Further information here: http://www.cplusplus.com/doc/tutorial/namespaces/
You cannot access x=10 in the inner block where you defined x=5. It can only see x=5 as x=10 is hidden at that point.
Ref: 3.3.7/1
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).
If you don't mind some horrible undefined behaviour, we could make assumptions about where local variables are stored on the stack. This works on my machineā¢ using g++ without any additional flags (although even -O1 breaks it):
#include <iostream>
using namespace std;
int x=15;
int main()
{
int x=10;
{
int x = 5;
cout<<*((&x) + 1); // should print 10;
}
return 0;
}
This is based on the assumption that local variables are placed on the call stack (or some other place) consecutively in main memory, in reverse order of declaration. It breaks in many cases, such as having a different order, having x=10 be placed in a register, or x=10 being optimized away entirely because it's unused.
#include <iostream>
using namespace std;
int x = 15;
int main()
{
int x = 10;
{
int x = 5;
}
cout << x; // should print 10;
return 0;
}
you should probably put cout<< to outside
I saw this below example in Geek For Geeks.
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
return x;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
Answer is 30.
But i am unable to map, how this value is arrived at. Please help me as to how this piece of code works.
After some answers from experts, i got to know the value assigned to function is assigned to static variable x which is equivalent to fun()::x =30
Now, i tried a different piece of code.. where in i have 2 static variables inside the fun() and returning the second variable reference. Still the answer is 30. Is is because when, fun() is assigned, it assigns the value 30 to all the variables inside fun()?
Second piece of code is
#include<iostream>
using namespace std;
int &fun()
{
static int x = 10;
static int y =20;
return y;
}
int main()
{
fun() = 30;
cout << fun();
return 0;
}
fun returns a reference (int&) to the static variable x inside funs scope. So essentially the statement fun() = 30 is fun::x = 30. Note this is only safe because x is static.
function local static variables get initialized the first time into the function and persist until the end of the program. So when you call
fun() = 30;
You return a reference to that variable and then assign 30 to it. Since the variable is still alive it will keep that value. Then
cout << fun();
Is going to return the variable again. Since it was already initialized it will not reset its value and it returns 30 as that is what it was set to in the preceding line.
When I run my code, attempting to return a local variable:
#include<iostream>
using namespace std;
int &fun()
{
int x = 30;
return x;
}
int main()
{
fun() = 10;
cout << fun();
return 0;
}
why does some compiler output 0 and some are 30
Returning a reference to a local variable that subsequently goes out of scope is undefined behaviour in C++.
Sometimes it might work, sometimes it might not. Occasionally the compiler might eat your cat.
Zombie.h has some static member variables. Read.cpp, which includes Zombie.h, knows the values that need to go in those variables. I want read.cpp to set those variables with something along the lines of
int Zombie::myStaticInt = 4;
or
Zombie::setStaticVar(4);
I've tried everything I can think of, including using a public static accessor function and even making the static variables themselves public, but I've been getting a lot of "undefined reference" or "invalid use of qualified-name" errors. By looking into those I found out how to set Zombie.h's private static member variables from Zombie.cpp, but I don't have a Zombie.cpp file, just read.cpp. Can I set them from Read.cpp instead, and if so, how?
// In Zombie.h
class Zombie {
public:
static void setMax(int a_in, int b_in, int c_in) {
a = a_in;
b = b_in;
c = c_in;
}
private:
static int a, b, c;
}
// In read.cpp
#include "Zombie.h"
...
main() {
int Zombie::a; // SOLUTION: Put this outside the scope of main and other functions
int Zombie::b; // SOLUTION: Put this outside the scope of main and other functions
int Zombie::c; // SOLUTION: Put this outside the scope of main and other functions
int first = rand() * 10 // Just an example
int second = rand() * 10 // Just an example
int third = rand() * 10 // Just an example
Zombie::setMax(first, second, third);
return 0;
}
This yields (Updated)
(Move first three lines of main outside of main() to solve this)
invalid use of qualified-name 'Zombie::a'
invalid use of qualified-name 'Zombie::b'
invalid use of qualified-name 'Zombie::c'
You have to define a,b,c somewhere. So far you've only declared them to exist. In some .cpp file, at the outer scope, you need to add:
int Zombie::a;
int Zombie::b;
int Zombie::c;
EDIT Re your edit, you can't put them inside a method. You have to put this at the outermost scope of the .cpp file.
Unlike non-static variables that get storage allocated in every object, static variables must have their storage outside of the class. You do this by creating definitions for the variables in a .cpp file. It doesn't matter which file they go in, although for convenience they should go with the code for the class.
int Zombie::a;
int Zombie::b;
int Zombie::c;
The linker error you're getting is telling you that these lines are missing.
Your problem is you haven't implemented Zombie class yet.
Your code here:
zombie.h
#ifndef ZBE_H
#define ZBE_H
class Zombie
{
public:
static int myStaticInt;
Zombie();
};
#endif
read.cpp
#include <stdio.h>
#include <iostream>
#include "zombie.h"
int Zombie::myStaticInt = 1;
Zombie::Zombie()
{
}
int main()
{
cout << "OOOK: " << Zombie::myStaticInt << endl;
Zombie::myStaticInt = 100;
cout << "OOOK: " << Zombie::myStaticInt << endl;
return 0;
}
In principle, a variable defined outside any function (that is, global, namespace, and class static variables) is initialized before main() is invoked. Such nonlocal variables in a translation unit are initialized in their declaration order
Above are the lines from the class notes given by my lecturer.
#include <iostream>
using namespace std;
int a=99;
int main(int argc, char *argv[])
{
cout<<a<<endl;
cout<<b<<endl;
return 0;
}
int b=100;
There is an error while I run this. Isn't it true that b assigned to 100 before main() is called?
The problem here is not initialisation order: b is indeed initialised before main starts running.
The problem is the "visibility" of b. At the point where main is being compiled, there is no b.
You can fix it by either moving the definition/initialisation of b to before main:
#include <iostream>
using namespace std;
int a = 99;
int b = 100;
int main (int argc, char *argv[]) {
cout << a << '\n';
cout << b << '\n';
return 0;
}
or simply indicate that b exists:
#include <iostream>
using namespace std;
int a = 99;
extern int b;
int main (int argc, char *argv[]) {
cout << a << '\n';
cout << b << '\n';
return 0;
}
int b = 100;
Neither of those two solutions change when b is created or initialised at run-time, they simply make b available within main.
Your lecturer is wrong; global variables are initialised in order of definition, not declaration.
For example,
#include <iostream>
struct S { S(const char *s) { std::cout << s << '\n'; } };
extern S a; // declaration
extern S b; // declaration
int main() { }
S b("b"); // definition
S a("a"); // definition
will print
b
a
The code you posted doesn't work because b is not even declared at the point of use. A declaration (for example, extern int b), is required because C++ (like C) was originally designed as a one-pass compiler.
The problem is here: cout<<b<<endl;
You can't access the variable before it's declaration.
Read carefully.
A variable defined outside any function (B) is initialized before main is invoked (not compiled).
To be compiled correctly B should be defined(and declared) before it's first use (and that's your error: B is used before been declared anywhere).
The problem is the statement b=100;: you can't place a statement in a global scope (except for variable initialization).
If this line remains as is, the code won't compile regardless of b declarations/definitions or the use of b within main or anywhere.
Without this line, the code is correct and works, with b value equals 0, since uninitialized global variables are initialized to 0 (or the line b=100; could be moved into any function scope).