Can anyone please tell me when the static variables/functions are allocated memory and in which memory segment? i.e. static global variable, static member variable, static local variable etc all are initialized once before the beginning of program and all retains its values?
Furthermore, If Class MyClass has static variable count, when I declare MyClass obj in main, then MyClass object is created and count is given memory, If I declared MyClass obj2, what happens in terms of memory? Is there any count in obj2 which refers to the count of obj1? Or there is only separate memory allocation. Hope so that I am able to clearly ask the question.
Thanks in advance.
When we declare a member of a class as static it means no matter how many objects of the class are created, there is only one copy of the static member. It exists even though no objects of the static data member's class exist.
A static member is shared by all objects of the class.
If I declared MyClass obj2, what happens in terms of memory? Is there any count in obj2 which refers to the count of obj1?
Yes. There is only one count for all objects. This test program would explain this a bit clear;
class Something
{
public:
static int s_nValue;
};
int Something::s_nValue = 1;
int main()
{
Something cFirst;
cFirst.s_nValue = 2;
Something cSecond;
std::cout << cSecond.s_nValue;
return 0;
}
output:
2
Because s_nValue is a static member variable, s_nValue is shared between all objects of the class. Consequently, cFirst.s_nValue is the same as cSecond.s_nValue.
Furthermore, If Class MyClass has tatic variable count, when I declare MyClass obj in main, then MyClass object is created and count is given memory
No. In fact, count exists even if there are no objects of the class have been instantiated!
The keyword static can probably be seen as somewhat "overloaded".
The following usage-options are all viable:
Static local variables
Static global variables
Static member variables
Static global functions
Static member functions
Variables:
In terms of runtime, all types of static variables are essentially the same. They all reside in the data-section of the program, and their addresses remain constant throughout the execution of the program. So the only difference between them is during compilation, in the scope of declaration:
Static local variable: recognized by the compiler only in the scope of the function
Static global variable: recognized by the compiler only in the scope of the file
Static member variable: recognized by the compiler only in the scope of the class
Functions:
In terms of runtime, all types of functions (static and non-static) are essentially the same. They all reside in the code-section of the program, and their addresses remain constant throughout the execution of the program. So the only difference between them is during compilation, in the scope of declaration:
Static global function: recognized by the compiler only in the scope of the file
Static member function: recognized by the compiler only in the scope of the class
The keyword static has different meaning depending on the context it is used in. static variables are allocated on the heap and their lifetime extends across the entire run of the program.
A static global variable is same as a global variable except that the static keyword limits the scope of the variable to the file containing it only. This is called file linkage or internal linkage.
A static member variable is created when the class containing it is defined. This means it can be accessed using the class's name. This variable is shared across all instances of the class.
A static local variable has the same lifetime as that of a static global variable except that its scope is the immediate block containing it.
When a function is qualified with the static keyword, this means that the scope of the function is the file containing it only. The function cannot be called by a function in another file. This is, again, called file scope or internal linkage.
Related
I saw this at work, and it is written by people before I joined. A static variable is used instead of static member of the class. As for now, I don't see a reason why static member of the class should not be used here. If I want to persuade people here to change it, is there any good excuse to convince them?
I tried to find the difference between static member and static variable, seems like people are leaning toward static member shall always be used unless there is a good reason, but not very real life cases were mentioned.
Current code:
class Foo {
public:
static Foo *get() {
static Foo _instance;
return &_instance;
}
// ...
};
How this function is being used:
int XXX_loadxxx(const char xxx, foo_handle *handle) {
// just get foo ptr and return
xxx::foo *ptr = xxx::foo::get();
int ret = ptr->init();
if (ret != 0) {
return -1;
}
*handle = ptr;
return 0;
}
Code in my mind how the class should be defined:
class Foo {
static Foo _instance;
public:
static Foo *get() {
return &_instance;
}
// ...
};
I'd really appreciate if someone can tell me whether it makes any different to change it to static member, and why.
The first solution is better for two reasons:
the static singleton is initialized the first time get() is called, which means you have a predictable behavior, which is not the case with static variables on different translation units
the variable is local so it's only visible from the getter of the singleton, which is usually what you want
I don't see why you would prefer to de-encapsulate it from the method.
Both samples cannot be compiled. What does the static Foo_instance mean? Did you mean static Foo instance?
Now back to your question: if you define the static variable inside of a function, it will be initialized only when you call the function for the first time. That has 2 consequences:
You will not spend resources if you never use this object;
If the constructor requires other resources to be allocated, you may need to control the time of creation. The time of creation of the static member is not defined.
The static member variable (as well as static variables in namespace scope) has a few disadvantages compared to a static local variable:
It must be defined in a single translation unit. This is not an option for libraries that desire to be "header only". This limitation no longer exists in C++17, which introduced inline variables.
The order of initialisation of static objects defined in different translation units is undefined. This often leads to undefined behaviour when static objects depend on other static objects, and may get initialised in the wrong order. This problem is called "Static Initialization Order Fiasco". The function local static (mostly1) solves this problem, since it is instead initialised on first use. As such, this idiom is called "Construct On First Use".
1 There is still a convoluted way of violating the ordering guarantees even with Construction On First Use: If there is static object A, whose constructor does not depend on static object B, but the destructor of A does depend on B, then B may still be destroyed first resulting in UB. This can be avoided by always calling the static getter of B in the constructor of A if any part of the A depends on B. In general, static objects should be avoided because of these problems.
P.S. Typically, you'd want to return a reference from the getter, so that the caller doesn't need to worry about getting null.
P.P.S. static Foo_instance; should probably be static Foo instance;
P.P.P.S. With the static member, the getter becomes mostly2 useless; the member could instead be made public.
2 It may still have some value if you intend to use inheritance, to extend the static object while maintaining compatibility with the original interface.
The local static varaible initialization is safe in a concurrent environment.
Another advantage is that it is initialized onlt in the case when the corresponding function is called. That is the variable is innitialized by a request.
From the C++ 17 Standard
4 Dynamic initialization of a block-scope variable with static storage
duration (6.6.4.1) or thread storage duration (6.6.4.2) is performed
the first time control passes through its declaration; such a variable
is considered initialized upon the completion of its initialization.
If the initialization exits by throwing an exception, the
initialization is not complete, so it will be tried again the next
time control enters the declaration. If control enters the
declaration concurrently while the variable is being initialized, the
concurrent execution shall wait for completion of the
initialization. If control re-enters the declaration recursively
while the variable is being initialized, the behavior is undefined
I am working with a class whose constructor declares and initializes a static const variable in the implementation. This is not a data member of the class. I understand the use of const in this context, but what is gained by using static?
I understand that the static const global constants are shared by all instances of the class. Does that also happen with the variable inside the constructor?
Also, why would this not be defined at the Global scope, like the other two? That's where I would normally define my constants.
Example Code:
#includes...
static const int GLOBAL_CONST1 = 100;
static const double GLOBAL_CONST2 = 1.0;
SomeClass::SomeClass()
:
theDataMember1 (),
theDataMember2 (),
...
{
static const double SOME_VAR = 0.01; // Why not declare this globally?
theDataMember1 = SomeIncludedClass(SOME_VAR);
}
Static Variable gets constructed only once no matter how many times the function is called.
So in case your defining constants inside a function and the function is called multiple times, then to reduce the cost of constructing this object every time the function is called you would make it a static variable (Mainly useful when its a constant, Else you may end up changing this value and it soon gets messed up).
For your second question, This is because you don't want others to be able to access the value of variable "SOME_VAR". Giving a global scope means any one can access it.
This link provides a good example about how local static is sometimes useful than global static variables.
When the constant is used only in one single function it can make sense to declare it only in the scope of the function it is used in. Why the static is used here does not really make sense to me, because it will be the same in all instances of the class anyway since it is a compile time constant.
But:
You can also initialize the constant from parameters computed at runtime. In that case the value of the constant will be defined by the first instance of the class:
class A {
public:
A(int param)
{
static const int MY_CONST = param;
cerr << "param: " << param << " const: " << MY_CONST << endl;
};
};
int main()
{
A a1(1);
A a2(2);
return 0;
}
output:
param: 1 const: 1
param: 2 const: 1
// Why not declare this globally?
By only seeing an abridged code fragment, we can only guess. It's typically good practice to put your variables in the narrowest scope possible. After all, everything could be global - we just choose to encapsulate things.
Perhaps the global constants are actually used in a lot of places, whereas the local constant is only used in that local function.
but what is gained by using static?
Probably just consistency. If you're just used to typing your constant values like:
static const T val = ddd;
everywhere, why change when you do it locally? There isn't an advantage or disadvantage of static for creating constant numbers.
static variables are literally static: they are allocated in same place as global variables. Plain local variables are allocated every time function is called on stack. If function is called n times recursively, there are n local variables. Static variable initialized only once. After it has been initialized, there is be only one instance of static variable. So static const local variable is used because of performance reasons.
Variables should have as narrow scope as possible to avoid unnecessary coupling. That's why this variable is local.
This looks like an attempt at premature optimization. Allegedly someone who created the code believed that by using static double variable they will save on creating the variable every time the function is entered.
However, since compilers are not morons, in practice it doesn't matter at all. Optimizing compilers will replace the variable with access to pre-allocated and initialized memory regardless, static or no static.
According to the OP's Code:
#includes...
static const int GLOBAL_CONST1 = 100;
static const double GLOBAL_CONST2 = 1.0;
SomeClass::SomeClass()
:
theDataMember1 (),
theDataMember2 (),
...
{
static const double SOME_VAR = 0.01; // Why not declare this globally?
theDataMember1 = SomeIncludedClass(SOME_VAR);
}
One has to take into consideration a few things:
Data Storage Unit - Storage Class Specifier
Data Storage Duration - Minimum Life Of Data
Scope Visibility - Where The Data Unit Is Visible.
Here is an excerpt:
Global objects and objects in a namespace scope, static data members of a class, and local static objects in functions reside static storage duration. An object with static storage duration resides in the same memory address throughout the program's execution. Every such object is constructed only once during the lifetime of the program. By default, static data is initialized to binary zeros. Static objects with a nontrivial constructor or an explicit dynamic initializer undergo a second initialization phase called dynamic initialization.
The scope of an object declared static in a function is restricted to that function. Objects with static storage duration appear in the following examples:
int num=0; //global variables have static storage
extern int x; //also global, defined in a separate translation unit
int func()
{
static int calls; //local static. initialized to 0 by default
x=calls;
return ++calls;
}
class C
{
private:
static bool b;
};
namespace NS
{
std::string str; //str has static storage
}
The extern Storage Class Specifier
The extern specifier can be applied only to the names of objects and to functions. The extern specifier cannot be used in the declaration of class members or function parameters. Identifiers declared extern have external linkage, meaning they are visible from all translation units of the same program.
A name declared in a namespace scope without a storage-class-specifier has external linkage unless it has internal linkage because of a previous declaration and provided it is not declared const. Objects declared const and not explicitly declared extern have internal linkage, meaning they are visible only from the translation unit in which they are declared.
Notice that the extern keyword is overloaded. It can also be used in explicit-instantiations of templates and in and linkage-specifications, but it is not a storage-class-specifier in such contexts.
The thread_local Storage Duration
The thread_local specifier indicates that the named object or reference has thread storage duration. thread_local shall be applied only to the names of objects or references of namespace scope and to the names of objects or references of block scope that also specify static as their storage class. The thread_local storage class is a new C++09 feature. It's discussed in detail here.
that can be found at this site: C++ Reference Guide | Static Storage Duration
The OP had stated and asked this:
I am working with a class whose constructor declares and initializes a static const variable in the implementation. This is not a data member of the class. I understand the use of const in this context, but what is gained by using static?
I understand that the static const global constants are shared by all instances of the class. Does that also happen with the variable inside the constructor?
Also, why would this not be defined at the Global scope, like the other two? That's where I would normally define my constants.
To answer his/her questions based on the excerpt above and from my own intuition:
their first question:
"What is gained by using static?" static data storage units have automatic initialization. They are created only once and reside in that same memory address or allocation unit.
their second question:
"Does that also happen with the variable inside the constructor?" Yes & No - Yes there is a single instance of this variable upon construction and initialization in the static storage memory unit, but no this is not visible to every instance of the class; it is only local to the Constructor of this class because of scope visibility.
their final question:
"Also, why would this not be defined at the Global scope, like the other two?" This particular variable depending on intention of use might only be used in the initialization of another object. One of the benefits of this maybe to not having to use a stack variable, and is only visible to this class' constructor. So when this constructor is called ctor this static const variable is created and initialize only once per construction and once this class object's constructor goes out of scope this static const variable is no longer visible by any other function or member of this class, or any other translation unit that is outside the visibility of this scope.
There is no definitive answer, however I tried to provide as much insight as I can in regards to the OPs questions, and tried to answer them to the best of my abilities. Some of the things that can vary are the intentions of the programmer and the context in which these memory allocations units are, declared, defined, initialized and then used.
this is the code snippet
static chck()//tracking how many times main has been called
{
static a=0;
int y=0;//this is not supposed to work
cout<<"Total time main has been called: ";
a++;
return a;
}
our teacher told us that static functions can't change or create non static variables
but it works for me ,why?
In this case "y" is a stack variable which this function can access.
The theory is static member functions (static Methods in a class) cannot access non static member variables (non static variables in the class) as there is no object as "this" inside a static member function.
static may well be the most overused keyword in c++. Your first use of it refers to the linkage of chck(), i.e. it has internal linkage. Your second use makes a static with respect to calls to ckch(), i.e. it's value will be preserved between calls. You are think of static member functions of a class that can't access non-static data members, i.e. those data members that are created per object instance.
I have a Code example here.
struct node {
int data;
struct node *link;
};
static struct node *first = NULL;
It would be great if someone could throw some light on my below questions about the usage of the word static.
What does the keyword static do in the above code?
what is the difference between normal structure and static structure?
It creates a static pointer to a node and initializez it to NULL.
The variable definition can have multiple meanings:
static struct node *first = NULL;
If defined outside of a method, it gives first internal linkage. It can only be used inside the defining module.
But you can also find that line inside a method:
void foo()
{
static struct node *first = NULL;
}
The variable is a method-scoped variable residing in static storage. It is initialized to NULL once and all subsequent changes persist between calls to the function.
It means that this variable may not be used outside this module.
E.g. - you cannot reference this pointer from another file using
extern struct node *first;
An important note is that the struct is not static, only first which is a pointer to such structure is static.
It doesn't affect the definition of the structure itself. It just means that the particular instance of the structure, named first here, has internal linkage.
The static keyword for a global variable makes the variable local to the module where it is defined. I.e. you cannot access it from another module.
If the static variable is defined within a function it keeps the variable alive and updated between calls to this function.
When modifying a variable, the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified. When modifying a variable or function at file scope, the static keyword specifies that the variable or function has internal linkage (its name is not visible from outside the file in which it is declared).
A variable declared static in a function retains its state between calls to that function.
When modifying a data member in a class declaration, the static keyword specifies that one copy of the member is shared by all instances of the class. When modifying a member function in a class declaration, the static keyword specifies that the function accesses only static members.
Static data members of classes must be initialized at file scope.
In recursive code, a static object or variable is guaranteed to have the same state in different instances of a block of code.
The members of a union cannot be declared as static. An anonymous union declared globally must be explicitly declared static.
Objects and variables defined outside all blocks have static lifetime and external linkage by default. A global object or variable that is explicitly declared as static has internal linkage.
Can static variables exist anywhere in C++ other than in a class? If so, what behaviour do they exhibit? I assume they're not being shared between instances as there is no object.
Yes.
The lifetime of a static object is the life of the program and the linkage of the object is internal if the variable is declared at file scope (and no linkage if defined at block scope).
Outside of a function, static means local to that compilation unit. You can achieve the same effect with an anonymous namespace.
Sure, of course, for example:
int sequence()
{
static int result = 0;
return ++result;
}
So, here, the result variable will continue to exist outside the scope of the function and constantly increase every time you enter the function.
Two other places:
Global variables and functions
Global static variables (or functions) are local to that compilation unit and cannot be "seen" from other compilation units
Local variables
static local variables are initialised once when their declaration is crossed for the first time (this is useful for doing things only on the first time a function is called), and after that they retain their value even after the function has returned and is called again
Note that these different uses of static really have nothing to do with each other. static means different things depending on where you use it, much like const.
It depends what you mean by a static variable. The static keyword has different semantics depending on the situation in which you use it.
Member variables, when declared as static, have static storage duration. This means the lifetimes of these variables lasts for the duration of the program. This is the common meaning of a 'static variable'. There are 3 cases under which a variable will have static storage duration:
When the static keyword is used on a local (function scope) variable.
When the static keyword is applied to a class member variable.
Any variable that does not have dynamic or thread storage duration and is not a local variable.
Example:
struct foo
{
static int x; // This has static storage duration
};
void bar()
{
static int y = 5; // This has static storage duration
}
int z = 1; // This has static storage duration
So to answer your question as if it were "Can variables have static storage duration when not members of a class?", the answer is yes. A global or namespace scope variable has static storage duration by default. A function scope variable declared as static also has static storage duration.
However, the static keyword has another meaning when it is used on variables in global or namespace scope. For these, static specifies that the variable has internal linkage. That is, they can only be referred to within the same translation unit.
Example:
static int i = 5; // This has internal linkage