Static initialization fiasco!

A

Andrea Crotti

I finally fell into this trap, I had a class which was specializing a
template with a "global" value.

Reading here and there I solved it like this below:

I'm not very convinced about the bool "uninitialized" value, another
better way?
Afterall it seems to work, but of course I have to write
GLOBAL()->value
every time I "need" something, but I guess there is no shorter way...

Globals.hpp:

#ifndef GLOBALS_H
#define GLOBALS_H

#include <ostream>
#include "Environment.hpp"
#include "Globals.hpp"
#include "SetID.hpp"
#include "ConfigParser.hpp"

const char CONFIG_FILE[] = "mobpad.ini";

// we really have to ensure that this works
struct GLOBALS_ST
{
int num_landmarks;
int trace_length;
int history_size;
int distribution_size;
SetID landmark_addresses;
ostream* out;
Environment *environment;
};

extern GLOBALS_ST GLOB;
struct GLOBALS_ST* GLOBAL();

#endif /* GLOBALS_H */

Globals.cpp:

#include <cstdlib>
#include "Globals.hpp"
#include "ConfigParser.hpp"
#include "SetID.hpp"
#include "Utils.hpp"

using namespace std;

static bool uninitialized = true;
GLOBALS_ST GLOB;

// not be seen by other files
static void setGlobals(GLOBALS_ST* glob)
{
ConfigParser c;
// first parse the file and then access to its fields
c.parse(CONFIG_FILE);
glob->num_landmarks = UTILS::strToInt(c["num_landmarks"]);
glob->trace_length = UTILS::strToInt(c["trace_length"]);
glob->history_size = UTILS::strToInt(c["history_size"]);
glob->distribution_size = UTILS::strToInt(c["distribution_size"]);
glob->landmark_addresses.add(UTILS::split(c["landmark_addresses"], ' '));
}

// if not set set it otherwise return the value
struct GLOBALS_ST* GLOBAL() {
if (uninitialized) {
// this memory is never freed, but is not such a big deal
setGlobals(&GLOB);
uninitialized = false;
}
return &GLOB;
}
 
V

Victor Bazarov

I finally fell into this trap, I had a class which was specializing a
template with a "global" value.

Reading here and there I solved it like this below:

I'm not very convinced about the bool "uninitialized" value, another
better way?

Your 'bool' is "statically initialized", you shouldn't worry about it.
Afterall it seems to work, but of course I have to write
GLOBAL()->value
every time I "need" something, but I guess there is no shorter way...

Globals.hpp:

#ifndef GLOBALS_H
#define GLOBALS_H

#include<ostream>
#include "Environment.hpp"
#include "Globals.hpp"
#include "SetID.hpp"
#include "ConfigParser.hpp"

You don't really need this to declare pointers to those classes.
Read up on forward declarations.
const char CONFIG_FILE[] = "mobpad.ini";

// we really have to ensure that this works
struct GLOBALS_ST
{
int num_landmarks;
int trace_length;
int history_size;
int distribution_size;
SetID landmark_addresses;
ostream* out;
Environment *environment;
};

extern GLOBALS_ST GLOB;
struct GLOBALS_ST* GLOBAL();

#endif /* GLOBALS_H */

Globals.cpp:

#include<cstdlib>
#include "Globals.hpp"
#include "ConfigParser.hpp"
#include "SetID.hpp"
#include "Utils.hpp"

using namespace std;

static bool uninitialized = true;
GLOBALS_ST GLOB;

// not be seen by other files
static void setGlobals(GLOBALS_ST* glob)

'static' in a declaration of a function is deprecated, I think.
{
ConfigParser c;
// first parse the file and then access to its fields
c.parse(CONFIG_FILE);
glob->num_landmarks = UTILS::strToInt(c["num_landmarks"]);
glob->trace_length = UTILS::strToInt(c["trace_length"]);
glob->history_size = UTILS::strToInt(c["history_size"]);
glob->distribution_size = UTILS::strToInt(c["distribution_size"]);
glob->landmark_addresses.add(UTILS::split(c["landmark_addresses"], ' '));
}

// if not set set it otherwise return the value
struct GLOBALS_ST* GLOBAL() {
if (uninitialized) {
// this memory is never freed, but is not such a big deal
setGlobals(&GLOB);
uninitialized = false;
}
return&GLOB;
}

There is no good work-around for that. You could use macros to
introduce the shorthand for all your 'GLOBALS()->' members, like

#define G_num_landmarks GLOBALS()->num_landmarks

etc.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top