Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Are static variables in C++ internal variables or external variables? Or can be both?
PS: It seems to me that (not sure it's correct):
Internal variables are assigned their values at compile time.
External variables are assigned their values at link time.
Initialization depends on the type of the static variable.
With fundamental types and initial values that can be computed at compile time, the variables initial value should be layed down in a section of the executable that is mapped into memory with copy on write semantics.
However, the compiler can also decide to initialize static variables at runtime, typically before main() gets executed. But afaik, the only constraint is that initialization is finished when the variable is first used, and that static variables within a compilation unit are initialized in the order they are written (in case their initializers depend on one another).
The point is, that static variables are initialized before they are used by code called from main(), but it is not specified when this initialization happens. The compiler can do what it deems most efficient.
In any case, static variables live at least until main() exits or exit() is called. I am pretty sure that C++ will also call the destructors before terminating the process, but I don't know about that.
According to the C++ Standard
3 A name having namespace scope (3.3.6) has internal linkage if it is
the name of — a variable, function or function template that is
explicitly declared static; or,
As for your statement that
PS: I learned that • Internal variables are assigned their values at
compile time.
• External variables are assigned their values at link time.
then it is wrong.
In my opinion you are trying to mix up two notions: static storage duration and program linkage.
Related
This question already has answers here:
Uninitialized variable behaviour in C++
(4 answers)
Closed 2 years ago.
If I don't initialize a C++ variable, I find that it automatically gives it 0 on some android phones, but not on others, and zero on all IOS phones.
So what determines whether you give it 0, is it the phone system, is it the compiler, is it some compiler option
It is undefined behaviour to read an uninitialized variable. If you do that your program is meaningless and the compiler is no longer required to generate anything sensible for the entire program.
What determines the initial value of C++ variables
If I don't initialize a C++ variable
I assume you refer to automatic storage. Variables in static or thread local storage are zero initialised implicitly.
From perspective of the language: The initial value is simply indeterminate. Whether anything affects this value indirectly is unspecified. The behaviour of reading an indetrminate value is in most cases undefined.
In practice: It is typically determined by whatever happens to be in the memory before it was allocated for the variable.
is it some compiler option
Perhaps, or maybe not. It's impossible to tell without seeing the compiler and options that were used.
I know that people have experimented with a compiler feature that initialises uninitialised variables, but I don't know of an official mainstream compiler release with such option. That doesn't mean it doesn't exist.
C++ variables are not warrantied to be initialized unless you define a constructor for the class of them.
In case of basic types or structs of basic types (aka POD, Plain Old Data) the value will be undefined unless you explicitly assign something to them.
Some compiler initialize them, some do it when you are generating debug information, but it is not a portable nor trusted way to do it.
You should not use uninitialized variables, as such will produce an undefined behavior.
My csapp book says that if global and static variables are initialized, than they are contained in .data section in ELF relocatable object file.
So my question is that if some foo.c code contains
int a;
int main()
{
a = 3;
}`
and example.c contains,
int b = 3;
int main()
{
...
}
is it only b that considered to be initialized? In other words, does initialization mean declaration and definition in same line?
It means exactly what it says. Initialized static storage duration objects will have their init values set before the main function is called. Not initialized will be zeroed. The second part of the statement is actually implementation dependant, and implementation has the full freedom of the way it will be archived.
When you declare the variable without the keyword extern you always define it as well
Both are considered initialized
They get zero initialized or constant initalized (in short: if the right hand side is a compile time constant expression).
If permitted, Constant initialization takes place first (see Constant
initialization for the list of those situations). In practice,
constant initialization is usually performed at compile time, and
pre-calculated object representations are stored as part of the
program image. If the compiler doesn't do that, it still has to
guarantee that this initialization happens before any dynamic
initialization.
For all other non-local static and thread-local variables, Zero
initialization takes place. In practice, variables that are going to
be zero-initialized are placed in the .bss segment of the program
image, which occupies no space on disk, and is zeroed out by the OS
when loading the program.
To sum up, if the implementation cannot constant initialize it, then it must first zero initialize and then initialize it before any dynamic initialization happends.
In the snippet:
int a;
int main()
{
a = 3;
}
a is not initialized; it is assigned. Assignment is a run-time execution of code. For example, should main be called multiple times (which is not, but any user function could), then a is set to 3 each time the function is called.
You second snippet is initializaion of the globalvariable b and it will be placed in the .data segment.
I will answer this question in general and complete way and not with respect to any programming language
There is a hell lot of confusion between declaration, definition, and initialization. Sometimes they all look similar and sometimes completely different.
Before understanding the differences, It is very important to be aware of two things:
The difference between declaration, definition, and initialization
varies from one programming language to other. Each programming has
its own way of doing these three things.The “thing” which you are
defining, declaring or initializing also affects the difference
between the three of them. That “thing” can be a variable, a class or
a function. All of them have different meanings of definitions,
declaration, and initialization. Once we are aware of the above two
things, most of the doubts get cleared and we stop seeking exact
differences because it’s not there.
In general terms ( irrespective of any language or “thing”)
The declaration means we are saying to a computer that this “thing”
(it can be a variable, a function or a class) exists but we don’t know
where. In the future, we may tell but right now it just exists
somewhere. In simple words, we don’t allocate memory while declaring.
We can declare that “thing” many times.
The definition means we are saying to the computer that this “thing” needs memory and it needs to be located somewhere. In simple
words, defining means we have allocated memory for it. We can define
something only once
The initialization means whatever our “thing “ is, we are giving it an initial value. That “thing” must be in some memory location and
if we keep that location empty, it may be a house for bugs and errors.
Initialization is not always necessary but it’s important.
Many people assume that declaration + definition = Initialization .
It's not wrong, but it’s not correct in all places. Its correct only for variables that too in a language like C ++ or maybe C.
In python, there is no concept of the declaration . We don’t need to declare anything in it.
The general meaning of the three is valid everywhere but the way that is performed varies from language to language and the “thing”.
Hope it helps :)
Variables with static storage duration that are initialized to zero end up in .bss.
Variables with static storage duration that are initialized with a non-zero value end up in .data.
NOTE: the C standard guarantees that if the programmer doesn't explicitly initialize a variable with static storage duration, such as static int a;, it is then initialized to zero implicitly1). Therefore a ends up in .bss.
Examples here.
1) C11 6.7.9
If an object that has static or thread storage duration is not initialized
explicitly, then:
if it has arithmetic type, it is initialized to (positive or unsigned) zero;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
So, just for my peace of mind, isn't it a logical error to assign a value to a static member variable within a class constructor?
Edit : I mean using the = operator
Won't the value keep changing with every object declared?
Suppose I send in a value to the constructor which I then use to set the value of a static variable. With each object declared the value of the static variable would keep changing.
It is only a logical error if you consider it to be one.
If however the change of the value of the static variable with each constructor is exactly what you WANT it to do, then it is not a logical error.
As in the comments already mentioned, one example is to count all constructors. This is often accompanied by also counting all DEstructors and in the end yields a count of existing instances.
The example could be implemented by using the = operator on the static variable,
count_of_ctors = count_of_ctors +1;;
though it probably would usually use ++,
count_of_ctors++;.
In the special case outlined in the question, setting a variable to a value given as parameter to the ctor, it could achieve the same, i.e. by giving the current value of the static variable, increased by one.
But you probably meant a value which is not derived from the current value of the static variable.
That still could be intended behaviour. I imagine that recording the last date+time of an instantiation could be such a value, which could serve debugging or logging purposes. That would be used by instantiating always with the current time.
Since the current time would probably better be read by the ctor (for convenience and for tampering protection), here is another idea. For each instantiation, the ID of the user (and maybe a matching passwort) has to be given, so that the static variable always has the last user ID which created an instance.
In C++ I know static and global objects are constructed before the main function. But as you know, in C, there is no such kind initialization procedure before main.
For example, in my code:
int global_int1 = 5;
int global_int2;
static int static_int1 = 4;
static int static_int2;
When are these four variables initialized?
Where values for initialization like 5 and 4 are stored during compilation? How to manage them when initialization?
EDIT:
Clarification of 2nd question.
In my code I use 5 to initialize global_int1, so how can the compiler assign 5 to global_int? For example, maybe the compiler first store the 5 value at somewhere (i.e. a table), and get this value when initialization begins.
As to "How to manage them when initialization?", it is realy vague and I myself does not how to interpret yet. Sometimes, it is not easy to explain a question. Overlook it since I have not mastered the question fully yet.
By static and global objects, I presume you mean objects with
static lifetime defined at namespace scope. When such objects
are defined with local scope, the rules are slightly different.
Formally, C++ initializes such variables in three phases:
1. Zero initialization
2. Static initialization
3. Dynamic initialization
The language also distinguishes between variables which require
dynamic initialization, and those which require static
initialization: all static objects (objects with static
lifetime) are first zero initialized, then objects with static
initialization are initialized, and then dynamic initialization
occurs.
As a simple first approximation, dynamic initialization means
that some code must be executed; typically, static
initialization doesn't. Thus:
extern int f();
int g1 = 42; // static initialization
int g2 = f(); // dynamic initialization
Another approximization would be that static initialization is
what C supports (for variables with static lifetime), dynamic
everything else.
How the compiler does this depends, of course, on the
initialization, but on disk based systems, where the executable
is loaded into memory from disk, the values for static
initialization are part of the image on disk, and loaded
directly by the system from the disk. On a classical Unix
system, global variables would be divided into three "segments":
text:
The code, loaded into a write protected area. Static
variables with `const` types would also be placed here.
data:
Static variables with static initializers.
bss:
Static variables with no-initializer (C and C++) or with dynamic
initialization (C++). The executable contains no image for this
segment, and the system simply sets it all to `0` before
starting your code.
I suspect that a lot of modern systems still use something
similar.
EDIT:
One additional remark: the above refers to C++03. For existing
programs, C++11 probably doesn't change anything, but it does
add constexpr (which means that some user defined functions
can still be static initialization) and thread local variables,
which opens up a whole new can of worms.
Preface: The word "static" has a vast number of different meanings in C++. Don't get confused.
All your objects have static storage duration. That is because they are neither automatic nor dynamic. (Nor thread-local, though thread-local is a bit like static.)
In C++, Static objects are initialized in two phases: static initialization, and dynamic initialization.
Dynamic initialization requires actual code to execute, so this happens for objects that start with a constructor call, or where the initializer is an expression that can only be evaluated at runtime.
Static initialization is when the initializer is known statically and no constructor needs to run. (Static initialization is either zero-initialization or constant-initialization.) This is the case for your int variables with constant initializer, and you are guaranteed that those are indeed initialized in the static phase.
(Static-storage variables with dynamic initialization are also zero-initialzed statically before anything else happens.)
The crucial point is that the static initialization phase doens't "run" at all. The data is there right from the start. That means that there is no "ordering" or any other such dynamic property that concerns static initialization. The initial values are hard-coded into your program binary, if you will.
When are these four variables initialized?
As you say, this happens before program startup, i.e. before main begins. C does not specify it further; in C++, these happen during the static initialisation phase before objects with more complicated constructors or initialisers.
Where values for initialization like 5 and 4 are stored during compilation?
Typically, the non-zero values are stored in a data segment in the program file, while the zero values are in a bss segment which just reserves enough memory for the variables. When the program starts, the data segment is loaded into memory and the bss segment is set to zero. (Of course, the language standard doesn't specify this, so a compiler could do something else, like generate code to initialise each variables before running main).
Paraphrased from the standard:
All variables which do not have dynamic storage duration, do not have thread local storage duration, and are not local, have static storage duration. In other words, all globals have static storage duration.
Static objects with dynamic initialization are not necessarily created before the first statement in the main function. It is implementation defined as to whether these objects are created before the first statement in main, or before the first use of any function or variable defined in the same translation unit as the static variable to be initialized.
So, in your code, global_int1 and static_int1 are definitely initialized before the first statement in main because they are statically initialized. However, global_int2 and static_int2 are dynamically initialized, so their initialization is implementation defined according to the rule I mentioned above.
As for your second point, I'm not sure I understand what you mean. Could you clarify?
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
int val1 = 0;
int val2 = 0;
int val3 = 0;
I don't understand why I have to put these = 0, is there any meaning behind it?
Initialisation of values to 0 or anything else is optional. If you don't though, the variable could contain anything...
This actually depends on where you declare the variables.
If you declare them as local variables (e.g. inside a function) then the compiler and runtime system will not initialize them, their values will be indeterminate. Using such variables except to initialize them will lead to undefined behavior.
If you declare them as global variables, then the compiler and runtime system will make sure that they are zero-initialized.
If you declare the variables as member variables inside a class or structure, then their initialization depends on if you have a constructor or not. If you don't have a constructor, or or a defaulted constructor, then the compiler will automatically generate a constructor which will default-construct the (non-static) members, which for int variables is the same as zero-initialization. If you have a constructor, the (non-static) member variables will be uninitialized just like local variables.
when declaring a new variable, it is stored on your current stack. it MIGHT have garbage in it from previous uses, so the only way to make sure you're new variable initial value is indeed 0 is setting it to zero when declaring