Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ late instantiation of global variable

Tags:

c++

c++11

I have code where a global resource has to be set up by quite some code:

globalClass foo;  // global variable / object; give it a memory space to live

void doSomething( void )
{
  foo.bar();      // use the global foo object
}

int main( int argc, const char *argv[] )
{
  foo( argc );   // foo can only be instantiated in main as it's using
                 // information that's only available here

  doSomething(); // use the global foo object

  return 0;
}

As you can see, foo is of global scope - but to call its constructor I need some information that's only available inside of main.

How can I achieve that?

The only solution I could figure out is to make foo a pointer to globalClass - but that would result in a pointer dereferencing each time I'm using foo. This might create a performance problem when used in a tight loop...

PS: In the real program main and doSomething would live in different files. And it's of course guaranteed that foo won't be accessed before it's instantiated.

like image 789
Chris Avatar asked Dec 01 '12 23:12

Chris


People also ask

Do global variables get initialized in C?

In C, static and global variables are initialized by the compiler itself. Therefore, they must be initialized with a constant value.

Are global variables slow in C?

Global variables are really slow, in addition to all the other reasons not to use them.

Are global variables initialized at compile time?

Global and static variables are initialized to their default values because it is in the C or C++ standards and it is free to assign a value by zero at compile time. Both static and global variable behave same to the generated object code.

Are global variables initialized to zero in C?

Yes, all members of a are guaranteed to be initialised to 0. If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.


1 Answers

Here's a really terrible hack if you don't want the indirection and don't mind doing the cleanup yourself:

union ClassHolder
{
    globalClass x;
    char buf[sizeof globalClass];

    constexpr ClassHolder() noexcept : buf() { }
};

ClassHolder h;
globalClass & foo = h.x;

int main()
{
    new (static_cast<void *>(&h.x)) globalClass(arg1, arg2, arg3);

    // main program

    h.x.~globalClass();
}
like image 128
Kerrek SB Avatar answered Oct 15 '22 11:10

Kerrek SB