0

I have a static library . I had gone through most of questions on stack overflow but could not come to a proper conclusion

C++ static initialization order

I have following files

File is myNew.h

#include <cassert>
#include <stdio.h>
void* operator new(size_t sz);

class myNew {
    public:
        myNew() {
            initialize();
        }
        static void* newPageCheck();
        static bool val;

    private:
        static void initialize();
};

File myNew.c

#include "myNew.h"
static myNew   myNewObj __attribute__ ((init_priority (80)));  
bool   myNew::val = false;

// overload default new operator 
extern void* operator new(size_t sz) {
    return myNew::newPageCheck();
}

void myNew::initialize() {
    val = true;
}

void* myNew::newPageCheck() {
    assert(val == true); 
    int i ; 
    return &i 
 }

File my_slib_new.h

#include <stdio.h>

class myFoo {
    public:
        myFoo() { 
            int *i = NULL;
            i = new int ;
            funS();
        }
        void funS();
 };  

File my_slib_new.cc

#include "my_slib_new.h"
static myFoo foo __attribute__ ((init_priority (2000)));

void myFoo::funS() {
    int *i = new int;
}

File sample_open_new.cpp

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "my_slib_new.h" 
int main () {
    printf ("Your Program will run ... \n");
    int status = open("./libSharedNew.so",0);
    return 0;
 }

I did following steps

Step 1: First created the the static library from myNew.cc

1) g++ -g -c -fPIC myNew.cc
2) ar rcs libStaticNew.a myNew.o

Step 2: Created shared library from my_slib_new.cc

3) g++ -g -c -fPIC my_slib_new.cc
4) g++ -shared -o libSharedNew.so my_slib_new.o

Step 3 :

5) gcc  -Wall -o myTest sample_open_new.cpp -L . -lSharedNew -lStaticNew

When I run myTest I get following assertion error

Assertion `MyNew::val == true' failed is because the static global object

static myFoo foo attribute ((init_priority (2000))); gets initialized before static global object

static myNew myNewObj attribute ((init_priority (80)));

My requirement is I cannot change linStaticNew.a to sharedLibrary .libStaticNew.a as to remain static only

I tried to delay the loading of Shared library by using open system call in sample_open_new.cpp but it did not work.

Is there is any way we can delay the loading of shared library libSharedNew.so , the idea is the static global object static myNew myNewObj attribute ((init_priority (80))); should be initialized first before static global myFoo object

or is there any we can specify the static global object of Static Library libStaticNew.a should be initialized first

Community
  • 1
  • 1
TechEnthusiast
  • 273
  • 4
  • 18

2 Answers2

0

Short answer: no, not like you are trying to do it.

Longer answer: yes, you should read up on the Static initialization order fiasco. Basically C++ gives no guarantee about the initialization order and the best advice is "avoid using global statics across different compilation units". But there are other options as well (mentioned in the FAQ linked above - here.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • is there any cleaner way I load the shared library at runtime . I do not link this to application but the load the shared library at runtime – TechEnthusiast Sep 04 '16 at 11:29
0

Use singletons. Meyers' singleton is easy, like this:

auto some_object()
    -> Object&
{
    static Object the_object;  // Possibly constructor arguments here
    return the_object;
}

Here the object is constructed on first use.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • Singletons cause so much trouble that I wouldn't recommend using them. As soon as they start depending on each other you have trouble destroying them in the right order and since they are destroyed after you leave `main` you have to make sure that they are ok with most of the world being gone at that time.. Just say no. They are an anti-pattern IMO and for good reasons. – Jesper Juhl Sep 04 '16 at 11:32
  • @JesperJuhl: Right you are. Don't use them in new code, if you can avoid it. But the advice is wrong in this context: this is about fixing a system which suffers from the static initialization order fiasco, and for this task singletons are “the” solution. It's even [a FAQ item](https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use), although the FAQ doesn't use the convenient Meyers' singleton of this answer. – Cheers and hth. - Alf Sep 04 '16 at 11:44
  • This technique often fails with third party libraries because while it guarantees the ordering of creation of your object's ctor and their object's ctor -- it doesn't guarantee the order of of of their object's ctor and any other static globals their object might be referring to. Especially in header only libraries. I've run into this before and it's an incredibly frustrating problem. – Chuu Jun 29 '18 at 15:53