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?

3
  • I don't know what you're asking. Commented Sep 27, 2016 at 18:39
  • I would have thought this error would be 'undefined identifier' rather than 'undeclared identifier' ?
    – lfgtm
    Commented Sep 27, 2016 at 18:49
  • It does seem like a strange diagnostic (even though the problem is not linkage so your suggested alternative isn't quite right) Commented Sep 27, 2016 at 18:56

2 Answers 2

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;
3
  • Then what is the solution?
    – Chang
    Commented Sep 27, 2016 at 18:47
  • @ChangLiao - answer improved
    – max66
    Commented Sep 27, 2016 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 = <value>; 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
    Commented Sep 27, 2016 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!

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.