I’m stuck with this dilemma where I need to use environment variables to initialize static variables in my application but from the C++ standard
Variables with static storage duration are initialized as a consequence of program initiation… —-ISO/IEC 14882:2020(E) section 6.9.3.2
But for me, it is also during this program initiation that my environment variables are set. So it ends up being that the variables get requested for when they have not yet been set.
Can you suggest a work around to solve this?
For namespace-level statics (probably what you're referring to), you can set your environment globals in main
, and then have your special globals in other cpp files initialize themselves from those first globals, and hope your compiler lazily initializes the globals in other cpp files, but.... that's pretty much the root cause of the static initialization order fiasco. It's a disaster, don't do that.
Instead, simply use method-level statics. This sidesteps the fiasco by guaranteeing that globals are initialized in the proper order, and is easy.
struct environment_t
{
/* •••Struct attributes to all variables••• */
};
//environment globals
const environment_t& env() {
static const environment_t values = {
std::getenv("PATH"),
std::getenv("HOME"),
std::getenv("SHELL"),
std::getenv("LOGNAME"),
std::getenv("UID"),
std::getenv("HOSTNAME"),
std::getenv("MAIL"),
std::getenv("EDITOR"),
std::getenv("TEMP"),
/* •••Other variables••• */
};
return values;
}
// derived globals
const std::string& app_data_directory() {
static const std::string value(env().home + "app/data"s);
return value;
}
// safe and easy!
int main() {
std::cout << app_data_directory();
}