Partially initialize a variable defined in another module

I am considering a specific solution in which I would like to initialize an array cell that is defined in another module (there will be many modules initializing one table). The array will not be read before starting main (therefore, there is no problem with the static initialization order).

My approach:

/* secondary module */

 extern int i[10]; // the array

 const struct Initialize {
  Initialize() { i[0] = 12345; }
 } init;


/* main module */

 #include <stdio.h>


 int i[10];

 int main()
 {
  printf("%d\n", i[0]); // check if the value is initialized
 }

The compiler will not allocate a constant initbecause the constructor has side effects. I'm right? Is the mechanism OK? On GCC (-O3), everything is fine.

//EDIT
. , , ( ). , .

+3
5

MSVC, GNU ++ ( ). GNU- , . ​​ - "init once". :

init_once.h:

template <typename T>
class InitOnce
{
    T *instance;
    static unsigned refs;
public:
    InitOnce() {
        if (!refs++) {
            instance = new T();
        }
    }

    ~InitOnce() {
        if (!--refs) {
            delete instance;
        }
    }
};
template <typename T> unsigned InitOnce<T>::refs(0);

unit.h:

#include "init_once.h"

class Init : public InitOnce<Init>
{
public:
    Init();
    ~Init();
};
static Init module_init_;

secondary.cpp:

 #include "unit.h"
 extern int i[10]; // the array

 Init::Init()
 {
     i[0] = 12345;
 }
 ...
+3

 /*secondary module (secondary.cpp) */

  int i[10]; 
  void func()
  {
       i[0]=1;

  }

.

 /*main module (main.cpp)*/

  #include<iostream>

  extern int i[];
  void func();
  int main()
  {
     func();
     std::cout<<i[0]; //prints 1
  }

, g++ secondary.cpp main.cpp -o myfile

( ) .

0

, extern int i[10]; , , adf88.

0

, . / undefined, , , ( ). , , second.c Initialize() ctor run . , , .

, , ( ) . init-order , , ( concurrency). -

/ (main.c)/

#include   CommonDat   {   int i;

public:
    const int GetI()    { return i;}
    void SetI(int newI) { i = newI; }
    void incI()         
     {
      AcquireSomeLock();
      i++;
      ReleaseTheLock();
     }
}

CommonDat g_CommonDat;
CommonDat*  getCommonDat()   { return &g_CommonDat; }

int main(void)
{
     printf("%d",getCommonDat()->GetI()); 
}

, ( c'tors).

(: C, ++. - ++, ).

0
source

May I ask why you are using an array (risking going out of bounds) when you can use std::vector?

std::vector<int>& globalArray()
{
  static std::vector<int> V;
  return V;
}

bool const push_back(std::vector<int>& vec, int v)
{
  vec.push_back(v);
  return true; // dummy return for static init
}

This array is lazily initialized the first time the function is called.

You can use it like this:

// module1.cpp
static bool const dummy = push_back(globalArray(), 1);

// module2.cpp
static bool const dummy = push_back(globalArray(), 2);

This seems to be much simpler and less error prone. It does not support multithreading up to C ++ 0x.

0
source

Source: https://habr.com/ru/post/1753341/


All Articles