C++ Programming Practices – Using const_cast and volatile for Global Parameters

cglobalsparametersprogramming practices

I have a program that I run repeatedly with various parameter sets. Different parameters are used in different parts of the program (including different source files). The same parameter may also be used in different places. However, all parameters are constant during run-time after they have been set.

I discovered very quickly that declaring the parameters locally does not make sense (it involves having to remember where every parameter is defined, etc.), so I resorted to using a params.h where I declared and defined all the parameters: const int Param1 = 42;, etc.

The downside of this is that I have to recompile every time I change a parameter. So I'm thinking of using the method below. It relies on usingvolatile and const_cast, which is normally considered "dirty", but it ensures once the parameters have been set in main, they are not accidentally changed anywhere else in the program.

I'm wondering whether people think this is OK, because eventually I want to open-source my code.

In params.h:

namespace Params
{
extern volatile const int Param1;
// etc.
}

In main.cpp:

#include "params.h"

volatile const int Params::Param1 = 0;

int main(int argc, char* argv[])
{
    int* const pParam1 = const_cast<int*>(Params::Param1);
    *pParam1 = // Get value from argv[] or some config.ini file.
    // etc.
}

Best Answer

Don't use volatile const, it sounds like nonsense! Instead, use a class/struct and initialize all variables in the constructor. You can still use const.

Params.h:

struct ConfigParams {

    const int param1;
    const int param2;
    // ...

    // Define a constructor that will load stuff from a configuration file.
    // Tune this to meet your needs, such as parsing the data from a startup command line.
    ConfigParams(const std::string & configFileName);
};

// The global that you will use to fetch the configurations during runtime.
extern const ConfigParams configParams;

Params.cpp:

// Declare the global configuration data table:
const ConfigParams configParams("app_configs.ini");

// The constructor:
ConfigParams::ConfigParams(const std::string & configFileName)
    : param1(getConfigFromFile(configFileName, "param1"))
    , param2(getConfigFromFile(configFileName, "param2"))
    // and so on ...
{
}

// And this function would open the file and lookup the requested parameter key, returning its value:
int getConfigFromFile(const std::string & configFileName, const std::string & key)
{
    // TODO...
}
Related Topic