g++ version 6.3.0 20170519 (Ubuntu/Linaro 6.3.0-18ubuntu2~14.04)
compilation and run commands used :
1) g++ -C singleton.cpp -fpic -shared -o libsingle.so
2) g++ -L/home/kapil/singleton test.cpp -o test -lsingle
3) ./test //error occurs after this command
Thanks alot JLBorges and Helios for taking time to analyze this and point out my mistakes :)
@JLBorges, though the implementation you suggested seems a bit scary :P :O, I'll try to understand future construct that you have used and find out how this program works.
@JLBorges : I have a small query about the above code mentioned by you
We have defined the static variable "the_only_one" of type singleton in function "singleton& singleton::instance()" for the following reasons :
1) This helps us not to worry about initialization order which we would not be sure if "the_only_one" was a
static member of the singleton struct ?
2) This make the code thread safe except for the boundary case mentioned by you ?
If not so, then please let me know what's the advantage of not making "the_only_one" as static class
member function.
> This helps us not to worry about initialization order
Yes.
> This make the code thread safe except for the boundary case mentioned by you ?
Yes. Technically, safe as long as control does not re-enter the declaration recursively while the variable (at block-scope with static storage duration) is being initialized.
9.7/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. 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.
[ Example:
1 2 3 4
int foo(int i) {
staticint s = foo(2*i); // recursive call - undefined
return i+1;
}
— end example ]
Foot note: The implementation must not introduce any deadlock around execution of the initializer. Deadlocks might still be caused by the program logic; the implementation need only avoid deadlocks due to its own synchronization operations. http://eel.is/c++draft/stmt.dcl