Static variable used in a template function - c++

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. …

Related

Can static variables be initialized multiple times?

I have read that static variables in c/c++ only initialised once.
But when i tried to experiment with it. I found that they can be initialised multiple times
#include <iostream>
#include <string>
using namespace std;
void demo(int value)
{
// static variable
static int count = 0;
count = value;
cout << count << " ";
}
int main()
{
for (int i=0; i<5; i++)
demo(i+1);
return 0;
}
In above code my initialised static variable count multiple times.
output is above code is : 1 2 3 4
is I am missing anything here?
count = value; is not initialization, it's assignment. Static variables can be assigned as many times as you wish.
static int count = 0; is initialization and that happens only once, no matter how many times you call demo.
Any variable can be initialized only once. Static is no different with respect to that. What is special about static local variables is that their value persists between function calls. And this of course only makes sense if the line that initialized it is only executed on the first function call. Consider this example:
#include <iostream>
#include <string>
using namespace std;
void demo()
{
// static variable
static int count = 0;
std::cout << ++count << " ";
}
int main()
{
for (int i=0; i<5; i++) demo();
return 0;
}
It prints
1 2 3 4 5
because the static in static int count = 0; means: only on the very first invocation of the function count is initialized with 0.
When a variable is declared as static, space for it gets allocated for the lifetime of the program.
Even if the function is called multiple times, space for the static variable is allocated only once and the value of variable in the previous call gets carried through the next function call.
count = value;-> This is assignment,and in this case static variables has same behavior like other data type (int for example).

Difference between Static variable declared in different scopes

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;
}

On local and global static variables in C++

C++ Primer says
Each local static variable 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 program
terminates.
Are local static variables any different from global static variables? Other then the location where they are declared, what else is different?
void foo () {
static int x = 0;
++x;
cout << x << endl;
}
int main (int argc, char const *argv[]) {
foo(); // 1
foo(); // 2
foo(); // 3
return 0;
}
compare with
static int x = 0;
void foo () {
++x;
cout << x << endl;
}
int main (int argc, char const *argv[]) {
foo(); // 1
foo(); // 2
foo(); // 3
return 0;
}
The differences are:
The name is only accessible within the function, and has no linkage.
It is initialised the first time execution reaches the definition, not necessarily during the program's initialisation phases.
The second difference can be useful to avoid the static intialisation order fiasco, where global variables can be accessed before they're initialised. By replacing the global variable with a function that returns a reference to a local static variable, you can guarantee that it's initialised before anything accesses it. (However, there's still no guarantee that it won't be destroyed before anything finishes accessing it; you still need to take great care if you think you need a globally-accessible variable. See the comments for a link to help in that situation.)
Their scope is different. A global-scoped static variable is accessible to any function in the file, while the function-scoped variable is accessible only within that function.
Hopefully, this example will help to understand the difference between static local and global variable.
#include <iostream>
using namespace std;
static int z = 0;
void method1() {
static int x = 0;
cout << "X : " << ++x << ", Z : " << ++z << endl;
}
void method2() {
int y = 0;
cout << "Y : " << ++y << ", Z : " << ++z << endl;
}
int main() {
method1();
method1();
method1();
method1();
method2();
method2();
method2();
method2();
return 0;
}
output:
X : 1, Z : 1
X : 2, Z : 2
X : 3, Z : 3
X : 4, Z : 4
Y : 1, Z : 5
Y : 1, Z : 6
Y : 1, Z : 7
Y : 1, Z : 8
There real name is:
static storage duration object.
Global variables are also 'static storage duration object'. The major difference from global variables are:
They are not initialized until the first use
Note: An exception during construction means they were not initialized and thus not used.
So it will re-try the next time the function is entered.
Their visability is limited by their scope
(ie they can not be seen outside the function)
Apart from that they are just like other 'static storage duration objects'.
Note: Like all 'static storage duration objects' they are destroyed in reverse order of creation.
The main or most serious difference is time of initialization. Local static variables are initialized on first call to function where they are declared. The global ones are initialized at some point in time before the call to main function, if you have few global static variables they are intialized in an unspecified order, which can cause problems; this is called static initialization fiasco.
In your first code block, x is local to the foo() function which means that it is created in foo() and destroyed at the end of the function after cout. However, in your second block x is global which means that the scope of x is the entire program. If you wanted to under int main your could cout << x << endl and it would print however, in the first block it would say x not declared
They are known to all functions in a program whereas global
variables are known only in a limited scope.
Global static variables can be initialized before the program starts whereas local static variables can be initialized as execution reaches point.

How do static variables in lambda function objects work?

Are static variables used in a lambda retained across calls of the function wherein the lambda is used? Or is the function object "created" again each function call?
Useless Example:
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
void some_function()
{
std::vector<int> v = {0,1,2,3,4,5};
std::for_each( v.begin(), v.end(),
[](const int &i)
{
static int calls_to_cout = 0;
cout << "cout has been called " << calls_to_cout << " times.\n"
<< "\tCurrent int: " << i << "\n";
++calls_to_cout;
} );
}
int main()
{
some_function();
some_function();
}
What is the correct output for this program?
Is it dependent on the fact if the lambda captures local variables or not? (it will certainly change the underlying implementation of the function object, so it might have an influence) Is it an allowed behavioural inconsistency?
I'm not looking for: "My compiler outputs ...", this is too new a feature to trust current implementations IMHO. I know asking for Standard quotes seems to be popular since the world discovered such a thing exists, but still, I would like a decent source.
tl;dr version at the bottom.
§5.1.2 [expr.prim.lambda]
p1 lambda-expression:
lambda-introducer lambda-declaratoropt compound-statement
p3 The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type — called the closure type — whose properties are described below. This class type is not an aggregate (8.5.1). The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. (My note: Functions have a block scope.)
p5 The closure type for a lambda-expression has a public inline function call operator [...]
p7 The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator [...]
Since the compound-statement is directly taken as the function call operator's body, and the closure type is defined in the smallest (innermost) scope, it's the same as writing the following:
void some_function()
{
struct /*unnamed unique*/{
inline void operator()(int const& i) const{
static int calls_to_cout = 0;
cout << "cout has been called " << calls_to_cout << " times.\n"
<< "\tCurrent int: " << i << "\n";
++calls_to_cout;
}
} lambda;
std::vector<int> v = {0,1,2,3,4,5};
std::for_each( v.begin(), v.end(), lambda);
}
Which is legal C++, functions are allowed to have static local variables.
§3.7.1 [basic.stc.static]
p1 All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these entities shall last for the duration of the program.
p3 The keyword static can be used to declare a local variable with static storage duration. [...]
§6.7 [stmt.dcl] p4
(This deals with initialization of variables with static storage duration in a block scope.)
[...] Otherwise such a variable is initialized the first time control passes through its declaration; [...]
To reiterate:
The type of a lambda expression is created in the innermost scope.
It is not created anew for each function call (that wouldn't make sense, since the enclosing function body would be as my example above).
It obeys (nearly) all the rules of normal classes / structs (just some stuff about this is different), since it is a non-union class type.
Now that we have assured that for every function call, the closure type is the same, we can safely say that the static local variable is also the same; it's initialized the first time the function call operator is invoked and lives until the end of the program.
The static variable should behave just like it would in a function body. However there's little reason to use one, since a lambda object can have member variables.
In the following, calls_to_cout is captured by value, which gives the lambda a member variable with the same name, initialized to the current value of calls_to_cout. This member variable retains its value across calls but is local to the lambda object, so any copies of the lambda will get their own calls_to_cout member variable instead of all sharing one static variable. This is much safer and better.
(and since lambdas are const by default and this lambda modifies calls_to_cout it must be declared as mutable.)
void some_function()
{
vector<int> v = {0,1,2,3,4,5};
int calls_to_cout = 0;
for_each(v.begin(), v.end(),[calls_to_cout](const int &i) mutable
{
cout << "cout has been called " << calls_to_cout << " times.\n"
<< "\tCurrent int: " << i << "\n";
++calls_to_cout;
});
}
If you do want a single variable to be shared between instances of the lambda you're still better off using captures. Just capture some kind of reference to the variable. For example here's a function that returns a pair of functions which share a reference to a single variable, and each function performs its own operation on that shared variable when called.
std::tuple<std::function<int()>,std::function<void()>>
make_incr_reset_pair() {
std::shared_ptr<int> i = std::make_shared<int>(0);
return std::make_tuple(
[=]() { return ++*i; },
[=]() { *i = 0; });
}
int main() {
std::function<int()> increment;
std::function<void()> reset;
std::tie(increment,reset) = make_incr_reset_pair();
std::cout << increment() << '\n';
std::cout << increment() << '\n';
std::cout << increment() << '\n';
reset();
std::cout << increment() << '\n';
A static can be constructed in the capture:-
auto v = vector<int>(99);
generate(v.begin(), v.end(), [x = int(1)] () mutable { return x++; });
The lambda can made by another lambda
auto inc = [y=int(1)] () mutable {
++y; // has to be separate, it doesn't like ++y inside the []
return [y, x = int(1)] () mutable { return y+x++; };
};
generate(v.begin(), v.end(), inc());
Here, y can also be captured by reference as long as inc lasts longer.
There are two ways to use states with lambdas.
Defining the variable as static in the lambda: the variable is
persistent over lambda calls and lambda instantiations.
Defining the variable in the lambda capture and mark the lambda as mutable: the variable is persistent over lambda calls but it is reset at every and lambda instantiations
The following code illustrate the difference:
void foo() {
auto f = [k=int(1)]() mutable { cout << k++ << "\n";}; // define k in the capture
f();
f();
}
void bar() {
auto f = []() { static int k = 1; cout << k++ << "\n";}; // define k as static
f();
f();
}
void test() {
foo();
foo(); // k is reset every time the lambda is created
bar();
bar(); // k is persistent through lambda instantiations
return 0;
}
I do not have a copy of the final standard, and the draft does not appear to address the issue explicitly (see section 5.1.2, starting on page 87 of the PDF). But it does say that a lambda expression evaluates to a single object of closure type, which may be invoked repeatedly. That being so, I believe the standard requires that static variables be initialized once and only once, just as though you'd written out the class, operator(), and variable capture by hand.
But as you say, this is a new feature; at least for now you're stuck with whatever your implementation does, no matter what the standard says. It's better style to explicitly capture a variable in the enclosing scope anyway.
The short answer: static variables declared inside of a lambda work the same as function static variables in the enclosing scope that were automatically captured (by reference).
In this case, even though the lambda object is returned twice, the values persist:
auto make_sum()
{
static int sum = 0;
static int count = 0;
//Wrong, since these do not have static duration, they are implicitly captured
//return [&sum, &count](const int&i){
return [](const int&i){
sum += i;
++count;
cout << "sum: "<< sum << " count: " << count << endl;
};
}
int main(int argc, const char * argv[]) {
vector<int> v = {0,1,1,2,3,5,8,13};
for_each(v.begin(), v.end(), make_sum());
for_each(v.begin(), v.end(), make_sum());
return 0;
}
vs:
auto make_sum()
{
return [](const int&i){
//Now they are inside the lambda
static int sum = 0;
static int count = 0;
sum += i;
++count;
cout << "sum: "<< sum << " count: " << count << endl;
};
}
int main(int argc, const char * argv[]) {
vector<int> v = {0,1,1,2,3,5,8,13};
for_each(v.begin(), v.end(), make_sum());
for_each(v.begin(), v.end(), make_sum());
return 0;
}
Both give the same output:
sum: 0 count: 1
sum: 1 count: 2
sum: 2 count: 3
sum: 4 count: 4
sum: 7 count: 5
sum: 12 count: 6
sum: 20 count: 7
sum: 33 count: 8
sum: 33 count: 9
sum: 34 count: 10
sum: 35 count: 11
sum: 37 count: 12
sum: 40 count: 13
sum: 45 count: 14
sum: 53 count: 15
sum: 66 count: 16

C++: Static variable declarations in a function

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.