Search code examples
c++structextern

Access external struct attribute from outside function


I was playing a bit with external variables and was wondering why I cannot access an external structure from outside functions?

Here's my code:

a.h

struct testing {

   unsigned int val;
   const char* str;

   testing(unsigned int aVal, const char* aStr) : val(aVal), str(aStr){};
}

extern testing externalStruct;

a.c

#include "a.h"

testing externalStruct(10, "test");

test.c

#include <iostream>
#include "a.h"

unsigned int valCopy = externalStruct.val;
const char* strCopy = externalStruct.str;

int main()
{
   std::cout<<"Direct val : "<<externalStruct.val<<std::endl; // Working, print 10
   std::cout<<"Direct str : "<<externalStruct.str<<std::endl; // Working, print "test"
   std::cout<<"Copy val : "<<valCopy<<std::endl; // Print 0 instead of 10
   std::cout<<"Copy str : "<<strCopy<<std::endl; // Print nothing

   return 0;
}

Any idea?


Solution

  • This problem is caused by the fact that order of initialization of static (global) variables is unknown. It even has a name static initialization order fiasco. This means that global variables from test.c translation unit were initialized before global variables from a.c transation unit.

    The usual solution is to use function with static variable. When function is called then static variable (during first use) is initialized. With c++11 initialization of such static function local variables is thread safe.

    Solution for your code could look as follows:

    a.h

    //...
    
    testing& GetExternalStruct();
    

    a.c

    //...
    
    testing& GetExternalStruct() {
       static testing externalStruct(10, "test");
       return externalStruct;
    }
    

    test.c

    unsigned int valCopy = GetExternalStruct().val;
    const char* strCopy = GetExternalStruct().str;