What is the difference between declaring static variable inside a block and outside a block in a file? Eg, here, what is difference between static variables a,b,c,d? Can we declare a static variable that is accessible from all files of a program?
static int a;
void getVol(..)
{
static int b;
}
int main()
{
static int c;
while(condition)
{
static int d;
....
}
some code here;
return 0;
}
Ultimately, there is no difference. Ignoring (for the moment) static member functions, static means what it means -- but we see different parts of what it means under different conditions because some of what it means can also happen without the keyword.
When you use the static keyword, the object being defined always has:
static lifetime -- it exists for the entire life of the program.
local visibility -- the name is not visible outside the scope in which it is declared.
Both of these are true about a static variable whether defined inside or outside a block. One part or the other will happen by default, even if you don't use the static keyword, but if you use the keyword, you always get both.
static member functions are analogous, but since they're functions they don't exactly have lifetime -- all functions have static lifetime. A static member function has local visibility (i.e., its name is visible only with its class) and something sort of like "static lifetime" -- the function isn't bound to an instance of the class.
For those who care about the specific time at which a block-level static variable is initialized, the gory details are as follows (§6.7/4):
The zero-initialization (8.5) of all block-scope variables with static storage duration (3.7.1) or thread storage duration (3.7.2) is performed before any other initialization takes place. Constant initialization (3.6.2) of a block-scope entity with static storage duration, if applicable, is performed before its block is first entered.
An implementation is permitted to perform early initialization of other block-scope variables with static or thread storage duration under the same conditions that an implementation is permitted to statically initialize a variable with static or thread storage duration in namespace scope (3.6.2). Otherwise such a variable is initialized the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization.
So, the variable will be zero-initialized very early in the startup of the program. Then, if other initialization has been specified, that will happen no later than when execution passes through the initialization (but could happen earlier than that). Note, however, the difference between constant initialization and other initialization. Just for example, consider something like this:
int g() { return 2; }
int f() {
goto bypass;
static int x = 1;
static int y = g();
bypass:
std::cout << x << "\n" << y;
}
Here, x is constant initialized, but y is not. Since x is constant initialized, it is initialized upon entry to the block, so when we print out its value, we should get 1. y, however, is not constant initialized, and the goto means that execution never flows through its initialization -- therefore, it will retain the 0 that it was initialized with before any other initialization took place, so (with a properly functioning compiler) the output will be:
1
0
Static variable inside a block(local static variable) -
It is not visible outside the block/function
It's value retains in function calls as it is static
Static variable outside a block(Global static variable) -
It's scope is the entire file(like a in your program)
It's value retains between function calls as it is static.
static int a;
means the variable a is a file scope variable, i.e, it can't be seen from other files.
void getVol(..)
{
static int b;
}
means the local variable b has a life cycle that goes from the program starts to the program ends, i.e, you can assign it some value, while on the next call of the function, it remembers that value.
c and d are similar to b.
The following worked for me:
/*
* How to create an object on the stack.
* Also make sure that only 5 objects are created for the class
*/
#include <iostream>
using namespace std;
class User {
private:
int id;
static int counter;
static bool isOk;
public:
User();
~User() {}
int getId() { return id; }
static int getCounter() { return counter; }
static bool getStatus() { return isOk; }
static void resetOk() { isOk = false; }
static void setOk() { isOk = true; }
};
User::User() {
if(counter == 5) {
cout << "Not allowed to create more than 5 objects" << endl;
resetOk();
return;
}
counter++;
id = counter;
setOk();
}
int User::counter = 0;
bool User::isOk = false;
int main()
{
// Create objects on stack
User user1;
(User::getStatus()) ? cout << "user1 id: " << user1.getId() << endl :
cout << "Object Construction Failed" << endl;
User user2;
(User::getStatus()) ? cout << "user2 id: " << user2.getId() << endl :
cout << "Object Construction Failed" << endl;
User user3;
(User::getStatus()) ? cout << "user3 id: " << user3.getId() << endl :
cout << "Object Construction Failed" << endl;
User user4;
(User::getStatus()) ? cout << "user4 id: " << user4.getId() << endl :
cout << "Object Construction Failed" << endl;
User user5;
(User::getStatus()) ? cout << "user5 id: " << user5.getId() << endl :
cout << "Object Construction Failed" << endl;
User user6;
(User::getStatus()) ? cout << "user6 id: " << user6.getId() << endl :
cout << "Object Construction Failed" << endl;
User user7;
(User::getStatus()) ? cout << "user7 id: " << user7.getId() << endl :
cout << "Object Construction Failed" << endl;
return 0;
}
static int a;//file scope variable
void getVol()
{
static int b;//fixed duration
}
File scoped variables act exactly like global variables, except their use is restricted to the file in which they are declared (which means you can not extern them to other files).
A fixed duration variable is one that retains it’s value even after the scope in which it has been created has been exited! Fixed duration variables are only created (and initialized) once, and then they are persisted throughout the life of the program.
Check this link:http://www.learncpp.com/cpp-tutorial/43-file-scope-and-the-static-keyword/
Using the static keyword in block scope is exactly like a global variable with respect to where it is stored, however the difference is that it is only accessible within the block scope that it was declared. Recall that as you nest blocks the inner-most block takes precedence when referencing an identifier -- which the same applies to static variables.
Consider the following snippet of code to illustrate my response:
#include <stdio.h>
void f1( void ) {
static int a = 10;
{
static int a = 9;
printf( "inner a = %d\n", a );
}
printf( "outer a = %d\n", a );
}
int main( void ) {
for ( int i = 0; i < 10; i++ ) {
printf( "Calling the function f1.\n" );
f1();
}
return 0;
}
Related
I am not able to understand the output of the below code:-
#include <iostream>
using namespace std;
template <typename T>
void fun(const T&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
int main(){
fun(1);
fun('A');
fun(1.1);
fun(2.2);
return 0;
}
Output:-
x = 1 count = 0
x = A count = 0
x = 1.1 count = 0
x = 2.2 count = 1
If value of static variable count is being reassigned to 0 whenever the function is called, then why its coming 1 when the function is being called fourth time.
And another thing , can we not pass "T x" directly instead of "const T&x"?
When a template gets instantiated, with explicit or deduced template parameters, it's as if a completely new, discrete, class or function gets declared. In your case, this template ends up creating three functions:
void fun<int>(const int &x)
void fun<char>(const char &x)
void fun<double>(const double &x)
It's important to understand that each one of these is a separate, standalone function, with its own static count variable. Because it's static, it gets initialized once, and its value is preserved across function calls. That's how static variables work in functions.
The shown code calls the first two once, and the third one twice. Those are the results you are seeing (the 2nd call to the third function incremented the same static count again).
Templates in C++ aren't generic functions like they are in Java. They're more like cookie cutters that make a new type-specific function for each type used to instantiate them. Your code is basically equivalent to this:
#include <iostream>
using namespace std;
void fun_int(const int&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
void fun_char(const char&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
void fun_double(const double&x){
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
int main(){
fun_int(1);
fun_char('A');
fun_double(1.1);
fun_double(2.2);
return 0;
}
And now it's obvious that you don't just have one static variable, but rather three different ones in different functions that just happen to have the same name.
If value of static variable count is being reassigned to 0 whenever the function is called...
That's where you're wrong. A static variable with an initializer (irrespective of its scope) is set to the value of the initializer once and once only. For static variables declared globally (in file scope), that initialization will be at program start-up; for static data declared in functions (as yours are), that initialization is deferred to the first time the function's code is executed.
Your code defines three different overloads of fun, each of which has its own copy of the local count variable. When the overload with the double argument is called the second time, the count variable will not be reinitialized – just incremented.
From this Draft C++17 Standard:
6.8.3.2 Static initialization [basic.start.static]
1 Variables with static storage duration are initialized as a consequence of program
initiation. …
and, for locally-declared static variables, we have this:
9.7 Declaration statement [stmt.dcl]
…
4 Dynamic initialization of a block-scope variable
with static storage duration or thread storage
duration is performed the first time control passes through its
declaration; such a variable is considered initialized upon the completion of its initialization. …
Chapter 6.1.1 of the book C++ Primer says the following:
Each local static object is initialized before the first time execution passes through the object’s definition. Local statics are not destroyed when a function ends; they are destroyed when the program terminates.
To check this, I ran the following code:
#include <iostream>
using std::clog;
using std::endl;
struct Bar {
Bar() {
clog << "constructing Num object" << endl;
}
int i = 0,
j = 0;
~Bar() {
clog << "destructing Num object" << endl;
}
};
void foo() {
clog << "foo() started" << endl;
static Bar b;
return;
}
int main() {
if (true) {
clog << "if-statement started" << endl;
foo();
}
clog << "if-statement exited" << endl;
return 0;
}
At this point in the book I haven't covered structs and classes yet, but it is my understanding that the function Bar() logs a message to the standard output when it gets created, and that b gets default initialized. If that is the case, then why does the output show that the object is constructed / initialized when control reaches static Bar b;, and not before it reaches this statement?
Output:
if-statement started
foo() started
constructing Num object
if-statement exited
destructing Num object
When are local static objects created?
As your book says: "before the first time execution passes through the object’s definition".
More precisely, the standard's wording is:
Dynamic initialization of a block-scope variable with static storage duration or thread storage duration is performed the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization.
I think you're getting too hung up on the word "before". 🙂
So there is something called static initialization and dynamic initialization and apparently they do not describe a certain way of initializing but when things are initialized. Static and dynamic initialization can only used to designate initializations of non-local variables...
So what about local variables? When do their initializations happen and what is it called? I cannot find anything called local initialization? I mean wouldn't it be quite convenient to have a name for when they are initialized since value-/ aggregate-/ etc. initializations describe what initialization happens and the can even be used with static and dynamic initialization(as far as I know) which makes it just a bit more confusing to me..
Hope this made somewhat sense to you :)
Local variables are initialised when they are constructed.
When doesn't need a name, only what is interesting.
Local variables are initialized when the scope is entered/reentered.
There is no specific terminology in c++ for local variable initialization.
Consider following example
for (int i = 0; i < 5; ++i) {
int n = 0;
printf("%d ", ++n);
/* prints 1 1 1 - the previous value is lost
every time n is initialized with 0 when scope is entered
*/
}
Simple logic is all local variables (static or dynamic) get initiated when only they are called in run time.
class Test
{
public :
Test(string text)
{
cout << (text) << endl;
}
};
void print()
{
Test t1("local");
static Test t2 ("local static");
}
int main(int argc, char* argv[]) {
cout << "begin" << endl;
print();
cout << "end" << endl;
}
anwers
begin
local
local static
end
There is a same question here : When exactly is constructor of static local object called?
but it only mentions on local static object, so i want add one more case for global static object.
Say we have 2 examples code like this:
Exam 1. local static ==========
class Mix {
Mix() { //the ctor code }
};
Mix& globalFunction()
{
static Mix gMix; // when its ctor execute ?
return gMix;
}
Exam 2. global static ==========
class Mix {
Mix() { //the ctor code }
static MyClass MReen; // when its ctor execute ?
};
//initialization static var
MyClass Mix::MReen = 0 ;
When exactly 'the constructor code' of 2 static objects above is executed ?
How is it on different between g++ (run on Linux) and VC++ compiler ?
Thanks
I try to test again code from Adam Pierce at here, and added two more cases: static variable in class and POD type. My compiler is g++ 4.8.1, in Windows OS(MinGW-32).
Result is static variable in class is treated same with global variable. Its constructor will be called before enter main function.
Conclusion (for g++, Windows environment):
Global variable and static member in class: constructor is called before enter main function (1).
Local static variable: constructor is only called when execution reaches its declaration at first time.
If Local static variable is POD type, then it is also initialized before enter main function (1).
Example for POD type: static int number = 10;
(1): The correct state should be: "before any function from the same translation unit is called". However, for simple, as in example below, then it is main function.
include < iostream>
#include < string>
using namespace std;
class test
{
public:
test(const char *name)
: _name(name)
{
cout << _name << " created" << endl;
}
~test()
{
cout << _name << " destroyed" << endl;
}
string _name;
static test t; // static member
};
test test::t("static in class");
test t("global variable");
void f()
{
static test t("static variable");
static int num = 10 ; // POD type, init before enter main function
test t2("Local variable");
cout << "Function executed" << endl;
}
int main()
{
test t("local to main");
cout << "Program start" << endl;
f();
cout << "Program end" << endl;
return 0;
}
result:
static in class created
global variable created
local to main created
Program start
static variable created
Local variable created
Function executed
Local variable destroyed
Program end
local to main destroyed
static variable destroyed
global variable destroyed
static in class destroyed
Anybody tested in Linux env ?
A local static variable, declared in an function, is initialised before the first call to the function. You can read more about this aspects of C++ standard here https://stackoverflow.com/a/58804/747050.
Global static variable is initialised before main(), but if you have several files the order is not garantied even within one compiler. Here is related answers: http://www.parashift.com/c++-faq/static-init-order.html , Can the compiler deal with the initialization order of static variables correctly if there is dependency?
p.s. You can guarantee the order for const static with one trick:
int YourClass::YourStaticVar()
{
static const int value = 0;
return value;
}
Static variables exist outside of the function, in terms of their memory at least (not scope), right? But one thing that always concerned me, is what happens when I call the function a second time. For instance:
f(){
static char buffer[256*256];
stuff(buffer);
}
When I call this function a second time, wouldn't it technically be declaring the variable 'buffer' a second time? Or does it work differently with static variables (as opposed to normal ones) once everything is compiled?
... I sometimes wish there was a chart or something of what a c++ compiler usually turns code into (minus optimizations) so I wouldn't have to bother you fine folks with little questions like this, aha. Thank you in advance!
edit: I know it works like this, I just want to know why though. It's probably something mind numbingly simple...
Static storage duration objects in function scope.
These objects are created on first use.
Then destroyed in reverse order of creation (with other static storage duration objects).
#include <iostream>
class X
{
public:
X(int x): m(x) {std::cout << "X: " << m << " created\n"; }
~X() {std::cout << "X: " << m << " destroyed\n";}
private:
int m;
};
static X x1(1);
int test()
{
std::cout << "Test: Start\n";
static X x3(3);
std::cout << "Test: Finished\n";
return 5;
}
int main()
{
std::cout << "Main: Start\n";
X x2(2);
test();
X x4(4);
std::cout << "Main: Finished\n";
}
Now Try it: (comments added). SSDO => Static Storage Duration object.
g++ X.cpp
./a.out
X: 1 created // SSDO file scope.
Main: Start
X: 2 created
Test: Start
X: 3 created // SSDO created on first use (Notice not destroyed)
Test: Finished
Test: Start // Notice not created here.
Test: Finished
X: 4 created
Main: Finished
X: 4 destroyed
X: 2 destroyed // Main now really finished. after destroying local variables.
X: 3 destroyed // Destroy SSDO in reverse order of creation. (3 - 1)
X: 1 destroyed
No, you static means that it is outside the scope of your function. It has the same effect as writing:
static char buffer[256*256];
f(){
stuff(buffer);
}
Except that the buffer is only visible in the scope of your function, and the code is more readable.
(NOTE: My example doesn't apply when char is not a primitive type - in that case, it is constructed the first time it is "declared").
In this context, static means that the variable has application lifetime. It is allocated before main() the function is entered, and deallocated after main() has returned. Also, its value is preserved between function calls. Think of it as a global variable that is only visible from inside that function.
The variable exists before and after you call the function...it's static.
This example might illustrate it:
#include <iostream>
using namespace std;
void test() {
static int i = 123;
if (i == 123) {
i = 321;
}
cout << i << endl;
}
int main(int arg, char **argv) {
test();
test();
return 0;
}
The output is:
321
321
So "i" is only initialized the first time it is encountered, so to speak. But actually it's allocated at compile time for that function. Afterwards, it's just in the scope of the function test() as a variable, but it is static so changing it changes it in all future calls to test() as well.