1

Basically I want to use a global constant in std::array in another file.

I am aware of that global variable question has been asked many times here. For example, this one: Defining global constant in C++

And personally I prefer to use method 5 or 6:

5: const int GLOBAL_CONST_VAR = 0xFF;

6: extern const int GLOBAL_CONST_VAR; and in one source file const int GLOBAL_CONST_VAR = 0xFF;

My project requires a lot of constants, such as the solar constant. And some are used for std::array, for example, nvegetation_type , nrock_type.

I used to use the method 5, so only one header is used for all other source files. But the multiple definition problem arises similar to: Multiple definition and header-only libraries and here: Why aren't my include guards preventing recursive inclusion and multiple symbol definitions?

But this looks like not a problem in my Visual Studio C++ project and I have no idea why yet. I used makefile under Linux and it also compiled.

However, when I use method 6 and define array in other source header file in C++11 as

extern const int nvegetation_type ;
const std::array< double, nvegetation_type > some_variable
 = { { 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 
       0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1} };

I will receive errors like:

 error C2065: 'nvegetation_type': undeclared identifier.

I am assuming when I use header/source approach, I cannot directly cross refer global variables, at least for std::array. I read some similar links, but none has mentioned this (Maybe my search was unlucky). http://www.learncpp.com/cpp-tutorial/42-global-variables/ So what is the solution?

Community
  • 1
  • 1
Chang
  • 396
  • 4
  • 17

2 Answers2

1

With

extern const int nvegetation_type;

you're saying to the compiler that, somewhere, is defined a constant but the compiler don't know the value in compilation phase.

And the compiler must know the exact value of the constant, in the compilation phase, for the following instruction

const std::array< double, nvegetation_type > some_variable 

So the error.

A simple solution could be use a header file where you can declare the const with it's value.

const int nvegetation_type = <value>;

(or even constexpr, taking in count that you have tagged the question as c++11) and include it in every cpp/h file where is needed.

The drawback is that, if you include this header in many cpp files, your program define many nvegetation_type constant; all with the same value but many copies.

In this case, you can add extern in the header

extern const int nvegetation_type = <value>;

and, in only one cpp file, add

const int nvegetation_type;
max66
  • 65,235
  • 10
  • 71
  • 111
  • Then what is the solution? – Chang Sep 27 '16 at 18:47
  • @ChangLiao - answer improved – max66 Sep 27 '16 at 18:56
  • Thanks, that is a very clear explanation. However, when I tested the last part, it turns out that In this case, you can add extern in the header extern const int nvegetation_type = ; and, in only one cpp file, add const int nvegetation_type; will cause the multiple definition problem, so I remove the .cpp file and it worked. @max66 – Chang Sep 27 '16 at 20:05
1

Thanks for all the comments and answers. I think I have fixed it with your helps.

Forgive me that I didn't provide enough details in the first place. I didn't put up a simpler demonstration of the problem I encountered. Usually I would created a test project.

So the final solution is a mixed one. As suggested above, the std::array requires the constant value to be known in compilation phase. The method 5 mentioned in my post is the ideal solution. In this case, only one header file is needed. It would be used in std::array. The drawback of this approach is that it will create multiple copies of the header file.

For other global variables, they can be defined using the method 6, the classical header and source files.

So I divided the global variables into two categories and define them using both method 5 and 6, respectively. And it worked!

Chang
  • 396
  • 4
  • 17