How to define constants in C ++ correctly

I see a common pattern in many C ++ codebases:

header.h:

static const int myConstant = 1; 

Source1.cpp:

 #include "Header.h" 

Source2.cpp:

 #include "Header.h" 

Based:

3.5 Program and communication

...

(2.1). If the name has an external reference, the object that it denotes can be called names from areas of other translation units or from other areas of the same translation unit.

(2.2). If the name has an internal relationship, the designated object may refer to names from other areas in the same translation unit.

...

3 A name that has a namespace scope (3.3.6) has an internal relationship if that name

(3.1) - a template for a variable, function, or function that is explicitly declared static; or,

myConstant is only available from the same translation unit, and the compiler will generate multiple instances, one for each translation unit, including Header.h .

Do I understand correctly - created several instances of myConstant ? If so, can you tell me the best alternatives to using constants in C ++

EDIT:

Some suggested making myConstant extern in the header and defining it in a single cpp file. Is this a good practice? I guess this will make the value invisible to the compiler and prevent many optimizations, for example, when the value appears in arithmetic operations.

+5
source share
2 answers

What you do should be good. The optimizer will probably not want to create some kind of storage for constants and will instead replace any use with its value if you never take the address of a variable (for example, &myConstant ).

+4
source

The static const int myConstant = 1 sample that appears in the header files is a bit strange because the static limits the scope of a variable to a specific translation unit. Therefore, this variable may not be available from other translation units. Therefore, I do not understand why someone can set a variable in the header file, although this variable can never be addressed externally.

Note that if different translation units include a header, then each translation unit will define its own, somewhat "private" instance of this variable.

I think the general template should be:

In the header file:

 extern const int myConstant; 

In one implementation file of the entire program:

 const int myConstant = 1; 

The comments say, however, that this will prevent the compiler from being optimized, since the constant value is not known at the time the translation unit is compiled (and that sounds reasonable).

So, it seems that the "global / general" constants are impossible and that a situation with the somewhat conflicting keyword static may occur in the header file.

Also, I would use constexr to specify a compile-time constant (although the compiler could still get it):

  static constexpr int x = 1; 

Since the static still bothers me, I did some research and experimentation on constexpr without the static , but with the extern keyword. Unfortunately, extern constexpr still requires initialization (which makes it a definition then and leads to duplication of character errors). Interestingly, at least with my compiler, I can actually define constexpr int x = 1 in different translation units without introducing a compiler / linker error. But I did not find support for this behavior in the standard. But the definition of constexpr int x = 1 in the header file is even more curious than static constexpr int x = 1 .

So - a lot of words, few conclusions. I think static constexpr int x = 1 is the best choice.

+1
source

Source: https://habr.com/ru/post/1269928/


All Articles