I have a global variable inside an anonymous namespace.
namespace {
std::unordered_map<std::string, std::string> m;
}
A::A() { m.insert(make_pair("1", "2")); } // crasches
void A::insert() { m.insert(make_pair("1", "2")); } // ok
If try to use the map inside the constructor I get Access violation reading location.
But if I use it after A has been initialized it works.Is this behavior correct?
What is the scope of the A object whose constructor invocation is causing the crash?
There are no guarantees as to the order that static initializers are executed, so that if your A object is also a global or static (as m is), it's quite possible that m does not exist yet in terms of being a validly constructed object, which would mean that your call to std::unordered_map::insert() would be invoked on uninitialized memory, thus leading to your crash.
A solution is to make sure that all of your A instances that depend on m are constructed explicitly by you and not statically/globally (or as the commenter added, if they are in the same TU, to order them properly), or to change the structure of A such that you can call a function on an instance later in order to do the insert. Whether or not this is a valid solution depends more on the overarching usage of A.
You are probably creating a class of type A in a static context somewhere in your application, ie before your main() function is executed, and therefore before m has been initialized.
Related
look at my code:
#include <iostream>
using namespace std;
class MyClass{
public:
char ch[50] = "abcd1234";
};
MyClass myFunction(){
MyClass myClass;
return myClass;
}
int main()
{
cout<<myFunction().ch;
return 0;
}
i can't understand where my return value is stored? is it stored in stack? in heap? and does it remain in memory until my program finished?
if it be stored in stack can i be sure that my class values never change?
please explain the mechanism of these return. and if returning structure is different to returning class?
MyClass myClass; is stored on the stack. It's destroyed immediately after myFunction() exits.
When you return it, a copy is made on the stack. This copy exists until the end of the enclosing expression: cout << myFunction().ch;
Note that if your compiler is smart enough, the second object shouldn't be created at all. Rather, the first object will live until the end of the enclosing expression. This is called NRVO, named return value optimization.
Also note that the standard doesn't define "stack". But any common implementation will use a stack in this case.
if returning structure is different to returning class?
There are no structures in C++; keyword struct creates classes. The only difference between class and struct is the default member access, so the answer is "no".
It's up to the implementation to find a sensible place to store that value. While it's usually on the stack, the language definition does not impose any requirements on where it's actually stored. The returned value is a temporary object, and it gets destroyed at the end of the full statement where it is created; that is, it gets destroyed at the ; at the end of the line that calls myFunction().
When you create an object in any function it's destroyed as soon as the function execution is finished just like in variables.
But when you return a object from a function firstly compiler creates a local instance of this object in heap called unnamed_temporary then destroyes the object you created. And copies the contents of unnamed_temporary on call. Then it destroyes this unnamed _temporary also.
Anything you create without the keyword new will be created in stack.
Yes,contets of your variable ch will not change unless you access that variable and change it yourself.
The instance returned by myFunction is temporary, it disappears when it stop to be useful, so it doesn't exist after after the cout <<.... Just add a destructor and you will see when it is called.
What do you mean about can i be sure that my class values never change? ? You get a copy of the instance.
returning structure is different to returning class? : a struct is like a class where all is public by default, this is the alone difference.
Your function is returning a copy of an object. It will be stored in the stack in memory.
The returning obj. will exist until the scope of that function. After that, it will be destroyed. Then, your expression cout<<function(); will also have the copy of that obj. which is returned by the function. IT will be completely destroyed after the running of this cout<<function(); expression.
Let's say I create:
class Hello {
public:
int World(int in)
{
static int var = 0; // <<<< This thing here.
if (in >= 0) {
var = in;
} else {
cout << var << endl;
}
}
};
Now, if I do:
Hello A;
Hello B;
A.World(10);
A.World(-1);
B.World(-1);
I'm getting output of "10" followed by another "10". The value of the local variable of a method just crossed over from one instance of a class to another.
It's not surprising - technically methods are just functions with a hidden this parameter, so a static local variable should behave just like in common functions. But is it guaranteed? Is it a behavior enforced by standard, or is it merely a happy byproduct of how the compiler handles methods? In other words - is this behavior safe to use? (...beyond the standard risk of baffling someone unaccustomed...)
Yes. It doesn't matter if the function is a [non-static] member of a class or not, it's guranteed to have only one instance of it's static variables.
Proper technical explanation for such variables is that those are objects with static duration and internal linkage - and thus those names live until program exits, and all instances of this name refer to the same entity.
Just one thing to add to the correct answer. If your class was templated, then the instance of var would only be shared amongst objects of the same instantiation type. So if you had:
template<typename C>
class Hello {
public:
int World(int in)
{
static int var = 0; // <<<< This thing here.
if (in >= 0) {
var = in;
} else {
cout << var << endl;
}
}
};
And then:
Hello<int> A;
Hello<int> B;
Hello<unsigned> C;
A.World(10);
A.World(-1);
B.World(-1);
C.World(-1);
Then the final output would be "0" rather than "10", because the Hello<unsigned> instantiation would have its own copy of var.
If we are talking about the Windows Compiler it's guaranteed
https://msdn.microsoft.com/en-us/library/y5f6w579.aspx
The following example shows a local variable declared static in a member function. The static variable is available to the whole program; all instances of the type share the same copy of the static variable.
They use an example very similar to yours.
I don't know about GCC
Yes, it is guaranteed. Now, to answer the question "Any risk of sharing local static variable of a method between instances?" it might be a bit less straightforward. There might be potential risks in the initialization and utilization of the variable and these risks are specific to variables local to the method (as opposed to class variables).
For the initialization, a relevant part in the standard is 6.7/4 [stmt.dcl]:
Dynamic initialization of a block-scope variable with static storage
duration (3.7.1) or thread storage duration (3.7.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.
In the simple cases, everything should work as expected. When the construction and initialization of the variable is more complex, there will be risks specific to this case. For instance, if the constructor throws, it will have the opportunity to throw again on the next call. Another example would be recursive initialization which is undefined behavior.
Another possible risk is the performance of the method. The compiler will need to implement a mechanism to ensure compliant initialization of the variable. This is implementation-dependent and it could very well be a lock to check if the variable is initialized, and that lock could be executed every time the method is called. When that happens, it can have a significant adverse effect on performance.
I have the following code:
void Foo() {
static std::vector<int>(3);
// Vector object is constructed every function call
// The destructor of the static vector is invoked at
// this point (the debugger shows so)
// <-------------------
int a;
}
Then somewhere I call Foo several times in a sequence
Why does the vector object gets constructed on every Foo() call and why is the destructor called right after static ... declaration?
Update:
I was trying to implement function once calling mechanism and I thought that writing something like
static core::CallOnce(parameters) where CallOnce is a class name would be very nice.
To my mind writing static core::CallOnce call_once(parameters) looks worse, but okay, this is the case I can't do anything with it.
Thank you.
Your variable needs a name:
static std::vector<int> my_static_vector(3);
You forgot to give the vector a name, so without any variable pointing to it it's destroyed immediately after it's created
Because std::vector<int>(3) creates an unnamed temporary, which lives only to the end of it's contained expression. The debugger can't show destruction in the same line as construction though, so it shows it on the next line.
Give the item an name and normal static semantics will apply.
MyClass GlobalVar;
int main()
{
MyClass VarInMain;
}
A couple of things:
Typically, they're allocated in different places. Local variables are allocated on the stack, global variables are allocated elsewhere.
Local variables in main are only visible within main. On the other hand, a global variable may be accessed anywhere.
More differences:
If constructor/destructor of global object throws an exception, then function terminate is called and there is no chance to proceed. For local object, you can catch exception and do something (but it is still tricky to throw from destructor).
Order of construction/destruction of global objects is not well specified. This means, that generally for two global objects you cannot say, which one is constructed first. From the other hand, local objects are created at point of defintion and destructed at end of block in order reverse to order of creation.
Scope... (already mentioned)
In general, it is not a good practice to use global objects without very strong reasons to do so. Using of globals often leads to code which is hard to maintain.
The variable VarInMain is a local variable and can only be used inside the function where it is declared, in your case, the main function. The GlobalVar can be used in every function of your program because it was declared outside of a function. This is called Scope.
Scope. VarInMain can be accessed directly only by code in main. GlobalVar can be accessed directly by code in any function in the file.
A simple example:
int y = 43;
void foo() {
// y is visible here, x is not
}
int main() {
int x = 42;
foo(); // x is visible here, but not when we enter the foo() function
}
A global variable is visible globally, across all functions.
A local variable is visible in the scope in which it is declared only. if you declare a local variable inside main, it will be visible there, yes, but not in functions that are called from main.
VarInMain is accessible only within the main() function. If main() calls another function, that function will not have access to it. This is function scope.
GlobalVar is accessible in every function in the same file. If you put extern MyClass GlobalVar; in a header, then it can be used in any function in files which have or include that declaration. This is global scope.
Another difference: the order of global object initilization is undefined.
For example:
static Integer Global_Integer(5);
static Foo Global_Foo;
As these are objects, the C++ runtime will call their constructors when initializing them, but we can't predict the order in which this will happen.
Another difference:
Global variables will be initialized before the program starts (i.e. main() gets called) whereas the local variables are initialized as execution reaches that point (i.e. just after main is called in the above example).
globals can be used in functions declared outside of main, while anything declared in main, must be passed to another function first.
Another one: The global variables (or variables in any other namespaces) are initialized to (T)0, with T being the type of the variable (in case it's a simple non-class type), arrays and classes are initialized like that for all their elements.
But in my opinion, it's a good idea to explicitly initialize things anyway, and not rely on that zero initialization since it improves readability of the program when the initial value is explicitly mentioned. It's however still useful to know when reading someone else's code, always keeping in mind the compiler will initialize those automatically.
The local variable when it is not declared static isn't automatically initialized. So you have to do any initialization on your own in case T has no constructor doing it for you. Always keep that in mind.
A global variable is accessible to any function. A variable in main acts exactly like any other local variable, and is only accessible to code in main.
Also, if main (or another function) calls itself, the local variables will be copied, but global variables will not.
int x = 0;
void myfunction()
{
x++;
printf("%i ",x);
}
int main()
{
myfunction();
myfunction();
}
This example will output:
1
2
Moving the "int x = 0;" into myfunction will output:
1
1
Because the local variable gets initialised each time myfunction is called.
LOCAL VARIABLE
It is a variable which is declared within a function or within a block. It is accessible only within a function/block in which it is declared.
GLOBAL VARIABLE
It is a variable declared outside all the functions. It is accessible throughout the program.
Can I control the order static objects are being destructed?
Is there any way to enforce my desired order? For example to specify in some way that I would like a certain object to be destroyed last, or at least after another static object?
The static objects are destructed in the reverse order of construction. And the order of construction is very hard to control. The only thing you can be sure of is that two objects defined in the same compilation unit will be constructed in the order of definition. Anything else is more or less random.
The other answers to this insist that it can't be done. And they're right, according to the spec -- but there is a trick that will let you do it.
Create only a single static variable, of a class or struct that contains all the other things you would normally make static variables, like so:
class StaticVariables {
public:
StaticVariables(): pvar1(new Var1Type), pvar2(new Var2Type) { };
~StaticVariables();
Var1Type *pvar1;
Var2Type *pvar2;
};
static StaticVariables svars;
You can create the variables in whatever order you need to, and more importantly, destroy them in whatever order you need to, in the constructor and destructor for StaticVariables. To make this completely transparent, you can create static references to the variables too, like so:
static Var1Type &var1(*svars.var1);
VoilĂ -- total control. :-) That said, this is extra work, and generally unnecessary. But when it is necessary, it's very useful to know about it.
Static objects are destroyed in the reverse of the order in which they're constructed (e.g. the first-constructed object is destroyed last), and you can control the sequence in which static objects are constructed, by using the technique described in Item 47, "Ensure that global objects are initialized before they're used" in Meyers' book Effective C++.
For example to specify in some way that I would like a certain object to be destroyed last, or at least after another static onject?
Ensure that it's constructed before the other static object.
How can I control the construction order? not all of the statics are in the same dll.
I'll ignore (for simplicity) the fact that they're not in the same DLL.
My paraphrase of Meyers' item 47 (which is 4 pages long) is as follows. Assuming that you global is defined in a header file like this ...
//GlobalA.h
extern GlobalA globalA; //declare a global
... add some code to that include file like this ...
//GlobalA.h
extern GlobalA globalA; //declare a global
class InitA
{
static int refCount;
public:
InitA();
~InitA();
};
static InitA initA;
The effect of this will be that any file which includes GlobalA.h (for example, your GlobalB.cpp source file which defines your second global variable) will define a static instance of the InitA class, which will be constructed before anything else in that source file (e.g. before your second global variable).
This InitA class has a static reference counter. When the first InitA instance is constructed, which is now guaranteed to be before your GlobalB instance is constructed, the InitA constructor can do whatever it has to do to ensure that the globalA instance is initialized.
Short answer: In general, no.
Slightly longer answer: For global static objects in a single translation-unit the initialization order is top to bottom, the destruction order is exactly reverse. The order between several translation-units is undefined.
If you really need a specific order, you need to make this up yourself.
Theres no way to do it in standard C++ but if you have a good working knowledge of your specific compiler internals it can probably be achieved.
In Visual C++ the pointers to the static init functions are located in the .CRT$XI segment (for C type static init) or .CRT$XC segment (for C++ type static init) The linker collects all declarations and merges them alphabetically. You can control the order in which static initialization occurs by declaring your objects in the proper segment using
#pragma init_seg
for example, if you want file A's objects to be created before file B's:
File A.cpp:
#pragma init_seg(".CRT$XCB")
class A{}A;
File B.cpp:
#pragma init_seg(".CRT$XCC")
class B{}B;
.CRT$XCB gets merged in before .CRT$XCC. When the CRT iterates through the static init function pointers it will encounter file A before file B.
In Watcom the segment is XI and variations on #pragma initialize can control construction:
#pragma initialize before library
#pragma initialize after library
#pragma initialize before user
...see documentation for more
Read:
SO Initialization Order
SO Solving the Order of Initialization Problem
No, you can't. You should never rely on the other of construction/destruction of static objects.
You can always use a singleton to control the order of construction/destruction of your global resources.
Do you really need the variable to be initialized before main?
If you don't you can use a simple idiom to actually control the order of construction and destruction with ease, see here:
#include <cassert>
class single {
static single* instance;
public:
static single& get_instance() {
assert(instance != 0);
return *instance;
}
single()
// : normal constructor here
{
assert(instance == 0);
instance = this;
}
~single() {
// normal destructor here
instance = 0;
}
};
single* single::instance = 0;
int real_main(int argc, char** argv) {
//real program here...
//everywhere you need
single::get_instance();
return 0;
}
int main(int argc, char** argv) {
single a;
// other classes made with the same pattern
// since they are auto variables the order of construction
// and destruction is well defined.
return real_main(argc, argv);
}
It does not STOP you to actually try to create a second instance of the class, but if you do the assertion will fail. In my experience it works fine.
You can effectively achieve similar functionality by having a static std::optional<T> instead of a T. Just initialize it as you'd do with a variable, use with indirection and destroy it by assigning std::nullopt (or, for boost, boost::none).
It's different from having a pointer in that it has preallocated memory, which is I guess what you want. Therefore, if you destroy it & (perhaps much later) recreate it, your object will have the same address (which you can keep) and you don't pay the cost of dynamic allocation/deallocation at that time.
Use boost::optional<T> if you don't have std:: / std::experimental::.