instantiate the value of "extern const"

Hello all,

I have a problem with regards instantiating global constant value.
I know at most of the time the following code works:

In header.h file:
1
2
3
4
#ifndef _HEADER_
#define _HEADER_
extern const int a;
#endif 



In header.cpp file:
const int a = 5;


And in main.cpp file:
1
2
3
4
#include "header.h"
int main(void){
  int b = a;
}



However, I encounter a problem which involves templates, and now the header file looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef _HEADER_
#define _HEADER_
extern const int a;

template <typename T>
void somefunction_1(){
   ... some action with T ... 

   someclass<a>();   # a class taking "a" as a "template" parameter
   somefunction<a>(); # a function taking "a" as a "template" parameter
}

#endif 


and "main.cpp" is:

1
2
3
4
#include "header.h"
int main(void){
  somefunction_1<int>();
}



The "someclass" and "somefunction" are well defined taking the value of "a" as template parameters (or whatever name of parameters) that MUST be instantiated as constant at compiling.

Then the problem arises:
If I follow the usual way, the compiler won't SEE the value of "a" at compiling "main.cpp", since "a" is instantiated when compiling the file "header.cpp".
If I declare the value a at .h file: " const int a = 5 ;" there will be a problem of multi-definition at linking when other files use the "header.h".


My current solution is assigning the value of a at both declaring stage and instantiating stage; that is:
In header.h file:
1
2
3
4
5
6
7
#ifndef _HEADER_
#define _HEADER_
extern const int a = 5 ;

....

#endif 


And in header.cpp file:
const int a = 5;


This passes the compiling and linking by g++ version 4.8.5.
As I'm not confident with this solution, I come for help to see if anyone would give me any suggestions or comments to this problem.

Thanks a lot first!
All the best!


BTW, I have no idea why the formatting scripts do not work on my screen. I tested with two different computers and two different browsers, neither of them worked. Sorry if the format puzzles you.

Edit: Thanks to Ganado, now I can format my thread.
Last edited on
> If I declare the value a at .h file: " const int a = 5 ;" there will be a problem of
> multi-definition at linking when other files use the "header.h".

const-qualified (non-volatile) variables which are not declared extern have internal linkage.

Place it in the header and declare it without extern : const int a = 5 ; or: constexpr int a = 5 ;
BTW, I have no idea why the formatting scripts do not work on my screen. I tested with two different computers and two different browsers, neither of them worked. Sorry if the format puzzles you.

It's not just you, it's a super annoying bug on this forum... You either have to type in the formatting manually ([code] [/code] for code excerpts, [b] for bold, [i] for italics, etc), or post and then edit your OP to add the code tags (the Format buttons will work once you edit your post).
Last edited on
Hello,

Thanks for your help.
It works as I expect.

However, I do not understand if we can declare and instantiate the const variable in header file, why many tutorials/threads suggest to declare the "extern const a" in header and instantiate "const a = 1" in cpp?

Is there any other reasons for such way of definition?

Thanks for your explanation!

Edit: I realize that the way I describe should be used to declare and instantiate global VARIABLE, not CONST.
This solves my puzzle.

Thanks!
Last edited on
execuse me, you need a const int number, could you use in other ways, ex:
1.use enum
enum {a=5};

2.use a class wrapper
struct A {
static const int a = 5;
};

3.constexpr int a() {return 5;}
@Jun Zhang2

I'm curious - why obfuscate your code that way?
@MikeyBoy

I just advise other ways to solve your problem since the matter of declaration , definition
and linkage is confusing. And I don't think it a good idea to use global variables.
But, as pointed out by JLB, declaring a const or a constexpr in a header isn't a global variable. It has internal linkage. And it's makes for simpler and more intuitive code than hiding a single const value inside a class, enum, or function that serves no other purpose other than to make a single const value available.

by definition, a variable is not a constant and a constant is not a variable. Variables' data varies (note the root word...) . Constants, however created, do not change**

** it is possible to override a global constant with a local copy of it with a different value and it is possible to redefine a #define, so you can monkey with constants to confuse people if you are feeling exceptionally evil. But at that point, they are actually 2 distinct constants that happen to have the same name, except for the case of undefine/define pairs, which is just an insane thing to do to yourself and your coworkers.

wrapping constants in objects is OOP for the sake of OOP. It brings nothing to the table in terms of readability or usage. It just bloats the code (physical text to be read by the programmer).
Last edited on
Registered users can post here. Sign in or register to post.