3
$\begingroup$

I am developing a code to simulate a Non-Volatile Memory (NVM). For that, I need several constants (memory dimensions, feature size, temperature etc.).

Until then, all my constants were defined at compile-time using pre-processor macros and constexpr variables. But as I needed to re-compile my code each time I wanted to modify the constants, I considered switching to run-time-defined variables.

I wanted to have two options to define the constants:

  1. Load the constants from a configuration file.
  2. Set them at the beginning of the execution manually (so that the code could be wrapped in another code).

I tried the proposal from these two questions:

Using a class to store the constants seems to be a good solution. However, it doesn't match exactly my requirements, as I would like to pass the constants/config file as a command line argument, facilitating code use in my opinion.
I also heard that boost library could do the work, but I heard that it has a quite expensive cost at compile and run time.

Do you think what I want to achieve is possible? Or am I taking the problem in the wrong way?

$\endgroup$
2
  • 2
    $\begingroup$ "but I heard that it has a quite expensive cost at compile and run time" -- surely initializing parameters isn't an expensive operation. So this is not something I would worry about. $\endgroup$ Dec 18, 2023 at 22:56
  • $\begingroup$ For my project, I load the options from a simple text file and they can be overwritten by command line arguments: github.com/cvanaret/Uno/blob/main/uno.options Arguably no best practice, but it's simple and works well (and I can use comments). $\endgroup$ Jan 22 at 17:26

2 Answers 2

7
$\begingroup$

Do yourself a favor and use JSON files for the configuration of your program. Nothing beats json in terms of extensibility and simplicity: Serialization (writing) and de-serialization (reading) of parameter sets comes out-of-the box. Everything is human-readable and -understandable. Arrays and subclasses/parameter-hierarchies are easily entered -- compare that, e.g. with boost.program_options, where it is pain. Moreover, new parameters can be added dynamically by adding text to the json file, so there is no need to parse for a positive list of parameter names as is done in boost.program_options. There are several header-only libraries in C++ which can deal with json.

One particular benefit in terms of code structure is that json also decouples the configuration and the actual C++ types of your application. For example, consider you are using an parameter of type int in an algorithm somewhere in your code. When you are working with the parameter classes as in the linked post, you usually forward this particular type to the classes for the parameter setup and reading. Later, if you change the int to long in the algorithm, say, you have to change the code at two different locations. Using a json file, you only have to change the parameter once in your algorithm.

$\endgroup$
3
  • 2
    $\begingroup$ I completely agree. JSON Files also have the advantage that they can be easily written by other programs aswell. That way you can have matlab or python or whatever write the json files and trigger your pipeline. That might not seem necessary now, but makes it a lot more comfortable to do parameter sweeps. $\endgroup$
    – MPIchael
    Dec 19, 2023 at 7:54
  • 3
    $\begingroup$ "Use JSON, everything is human-readable and -understandable" - I disagree. JSON requires rather strict quoting and escaping, and most importantly it does not allow comments. Use JSONC, JSON5, YAML or TOML instead, they are much better for configuration files written and edited by humans. $\endgroup$
    – Bergi
    Dec 19, 2023 at 9:48
  • 2
    $\begingroup$ @Bergi: Thank you for your comment. I was basically arguing against the C++ classes/boost.program_options approach, and in favor of the "domain-specific language" approach. So yes, your mentioned alternatives might also be valid choices for the latter. I would say it's a balance between the features you were mentioning and the simply much more widespread use of JSON. Regarding comments, one can use the approach presented here, not nice, but does the job. In summary, I'd still go with JSON, but that's only my take on the mentioned balance. $\endgroup$
    – davidhigh
    Dec 19, 2023 at 18:52
1
$\begingroup$

An alternative to JSON is to use Google’s protocol buffers.

You can think of it as a strongly typed generalization of JSON that allows for generating classes in your favorite language via compilation of a .proto file. After this is done, you will have C++ (or whatever language you want to use, like Python) files implementing the proto defined structure(s) as a class so you can use them in your C++ software. These are high performance implementations and easy to use. A plus is that the human readable format for protos are also very easy to understand, but you can also write binary versions of these formats when you want to save space (like for dumping complex data to disk).

One thing I also like about protobufs is by defining a proto definition for my structure, I have effectively documented what the types and possible variables are that can be stored in a way that can be version controlled. This can be a benefit in the long term for config file specifications as well as for output data files you might want to spit out from some software.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.