stephane
stephane

Reputation: 69

C++, Where To Put Free Variables?

I'm writing a small ini file parser (0), I use some regular expressions that I have put into a std::map<std::string, std::regex>, it's a const one because it contains all I need to retrieve the data from my customized ini format (1), but I don't know where (or rather: how and why) to put that variable in my source.

For the moment (until I find a solution), I've declared and defined it, in its header file, as a (non const (2)) member of one of the classes I write, inside a namespace, which class has its corresponding cpp implementation file. That class uses the map, but it could (and is pretty likely to) be used by other classes too.

And that's it, I don't know how I should handle it. What is sound and adequate?

Should I create a class/struct on its own for it, should I let it be a global variable, maybe a static, and/or constexpr'ifying it, or even typedef'ying it? Where to put it, as what?

I'm looking for conformity with the design of C++, its standards, best practices, and efficiency (3), reliability, maintainability, scalability, reusability, should I completely redesign the whole thing (4).


Note @moderators: I don't know how to formulate my question, so if any of you have a better idea for the title, then thank you for editing my post.


(0) It's for my own use, on Linux, so I don't worry too much about portability/compability, even if it's mostly for a learning purpose; I teach C++ myself, and I just want to understand... and I find many things very difficult to apprehend.

(1) It looks like so:

[sectionName]
str1="abcd efgh ijkl mnop"
str2 = "qrst uvw xyz"
boolean_item = true
double_value = 10.0
long_int = -2147483650

; this is a comment
[SecondSection]
str_list_item = "abc", "def", "ghi"
intListItem=2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
double_List_Item = 0.15, 16.00125, 748.963, 10247.4412578

[third_section]
hex_value = 0x4f0
bin_value = 0b11010001101110
; type annotations ?
; my_float: float = .03125

(2) I've read that according to isoccp we should “Avoid const member variable” (can't find the link, only a discussion on reddit), but it can be okay in some cases.

(3) At this point, tested with a 40 lines long ini file, a time ./test (compiled with -g -O0) returns the following average which looks slow to me:

real    0m0,023s
user    0m0,018s
sys     0m0,005s

(4) The whole things being interrelated as they depend on each others, as I understand it. In that regard, are there any design patterns that would be interesting to drive my project (the whole parser, not only the question of the variable)?

Upvotes: 1

Views: 86

Answers (1)

Patrick
Patrick

Reputation: 23629

Personal opinion: don't use global mutable (non-const) variables. Three main reasons to avoid them:

  • All of the code can access it, meaning you have no control over who can use it and who can't
  • Lifetime: who guarantees that no part of your code will access the global variable before it has been initialized; who guarantees that no part of your code will access the global variable after it has been cleaned up (well, maybe not a real problem in your case, but a real problem in many other cases)
  • Dependencies on other global variables: when you start to use global variables, you sometimes end up with global variables referring to other global variables, and then construction and destruction becomes a real nightmare.

Some of these problems are also valid for global constants. So, although I do allow global constants in my code, I only allow them if they are constexpr-constructible and trivially destructible.

Better to have a clear method that reads your INI file, and returns the map. Then pass the map to those methods/classes that need it. That way you have full control over the map.

Upvotes: 1

Related Questions