Define constant variables in C++ header
You could simply define a series of const ints
in a header file:
// Constants.h
#if !defined(MYLIB_CONSTANTS_H)
#define MYLIB_CONSTANTS_H 1
const int a = 100;
const int b = 0x7f;
#endif
This works because in C++ a name at namespace scope (including the global namespace) that is explicitly declared const and not explicitly declared extern has internal linkage, so these variables would not cause duplicate symbols when you link together translation units. Alternatively you could explicitly declare the constants as static.
static const int a = 100;
static const int b = 0x7f;
This is more compatible with C and more readable for people that may not be familiar with C++ linkage rules.
If all the constants are ints then another method you could use is to declare the identifiers as enums.
enum mylib_constants {
a = 100;
b = 0x7f;
};
All of these methods use only a header and allow the declared names to be used as compile time constants. Using extern const int
and a separate implementation file prevents the names from being used as compile time constants.
Note that the rule that makes certain constants implicitly internal linkage does apply to pointers, exactly like constants of other types. The tricky thing though is that marking a pointer as const
requires syntax a little different that most people use to make variables of other types const. You need to do:
int * const ptr;
to make a constant pointer, so that the rule will apply to it.
Also note that this is one reason I prefer to consistently put const
after the type: int const
instead of const int
. I also put the *
next to the variable: i.e. int *ptr;
instead of int* ptr;
(compare also this discussion).
I like to do these sorts of things because they reflect the general case of how C++ really works. The alternatives (const int
, int* p
) are just special cased to make some simple things more readable. The problem is that when you step out of those simple cases, the special cased alternatives become actively misleading.
So although the earlier examples show the common usage of const
, I would actually recommend people write them like this:
int const a = 100;
int const b = 0x7f;
and
static int const a = 100;
static int const b = 0x7f;
constant variables not working in header
The problem is that you define objects with external linkage in header file. Expectedly, once you include that header file into multiple translation units, you'll get multiple definitions of the same object with external linkage, which is an error.
The proper way to do it depends on your intent.
You can put your definitions into the header file, but make sure that they have internal linkage.
In C that would require an explicit
static
static const double PI = 3.1415926535;
static const double PI_under_180 = 180.0f / PI;
static const double PI_over_180 = PI/180.0f;In C++
static
is optional (because in C++const
objects have internal linkage by default)const double PI = 3.1415926535;
const double PI_under_180 = 180.0f / PI;
const double PI_over_180 = PI/180.0f;Or you can put mere non-defining declarations into the header file and put the definitions into one (and only one) implementation file
The declarations in the header file must include an explicit
extern
and no initializerextern const double PI;
extern const double PI_under_180;
extern const double PI_over_180;and definitions in one implementation file should look as follows
const double PI = 3.1415926535;
const double PI_under_180 = 180.0f / PI;
const double PI_over_180 = PI/180.0f;(explicit
extern
in the definitions is optional, if the above declarations precede the definitions in the same translation unit).
Which method you will choose depends on your intent.
The first method makes it easier for the compiler to optimize the code, since it can see the actual value of the constant in each translation unit. But at the same time conceptually you get separate, independent constant objects in every translation unit. For example, &PI
will evaluate to a different address in each translation unit.
The second method creates truly global constants, i.e. unique constant objects that are shared by the entire program. For example, &PI
will evaluate to the same address in each translation unit. But in this case the compiler can only see the actual values in one and only one translation unit, which might impede optimizations.
Starting from C++17 you get the third option, which sort of combines "the best of both worlds": inline variables. Inline variables can be safely defined in header files despite having external linkage
inline extern const double PI = 3.1415926535;
inline extern const double PI_under_180 = 180.0f / PI;
inline extern const double PI_over_180 = PI/180.0f;
In this case you get a named constant object whose initializer value is visible in all translation units. And at the same time the object has external linkage, i.e. it has a global address identity (&PI
is the same in all translation units).
Granted, something like that might only be necessary for some exotic purposes (most use cases in C++ call for the first variant), but the feature is there.
Linkage error for a header containing const variables and included in multiple files?
As mentioned in this internal linkage reference const
qualified names have internal linkage.
The problem is that your names are not const
qualified. The const
is for the data the pointers are pointing to, not for the variables themselves.
You need to add a const
in the correct place:
const wchar_t* const TEST_MUTEX_NAME = L"TestMutex";
// ^^^^^
// Make TEST_MUTEX_NAME itself constant
Is making a standalone header file for all the constant variables that many of your class may need a good practice?
The better practice is reducing the scope of all variables as much as possible. Ultimately reducing the pollution in the global space.
if the constants are only used in that class, keep it inside that class.
In the case where it makes sense to share a common constant value between all these classes, then having a common header file should be fine. But make sure the name is meaningful and hold consistent definitions between each usage.
You probably know this but, don't use globals just to be lazy. And document them properly I.e. Add appropriate comments next to the constants and why you chose the values may be.
How to declare constant parameters in separate class or header file in C++?
Why do you feel that you need a class for this? That doesn't seem appropriate. FORTRAN comparisons are also not likely to bear much fruit as C++ is a different language with different idioms and concepts.
To me, it seems like you should simply put those constants in a header file. Be sure to make them static const constexpr
to avoid linker clashes.
// Constants.hpp
#ifndef MYLIB_CONSTANTS_HPP
#define MYLIB_CONSTANTS_HPP
#pragma once
static constexpr const int Number_0 = 234;
static constexpr const float Number_1 = 34.76;
static constexpr const double Number_2 = 98.78;
#endif
Now you just #include "Constants.hpp"
in any translation unit that requires access to these values.
For the record, the old-school C approach to do the same thing would be to use #define
s.
Don't forget to give these constants meaningful names.
shared c constants in a header
In some .c file, write what you've written.
In the appropriate .h file, write
extern const char* QUERY; //just declaration
Include the .h file wherever you need the constant
No other good way :)
HTH
how to define constant variables in header files in C language
You should extern
you variable.
.h
file:
#ifndef HDR_H
#define HDR_H
typedef struct
{
int kind; /* it has a constant value 0x01*/
} tcp_opt_nop;
extern const tcp_opt_nop opt_nop;
#endif
.c
file:
#include "hdr.h"
const tcp_opt_nop opt_nop = {0x01};
main file:
#include "hdr.h"
int main()
{
printf("%i\n", opt_nop.kind);
// ...
}
Linking with constant variable definition in a header file
extern
tells the compiler that space is allocated for it somewhere else. There must be a definition of it somewhere without an extern on it. BUT in C++ (unlike C), consts have internal linkage, so you don't need the extern on it. (see Why does const imply internal linkage in C++, when it doesn't in C?)
Just put const int YEAR = 2011;
in your header file and include your header file where ever you need it.
Related Topics
C++ Comparison of Two Double Values Not Working Properly
Does "Undefined Behaviour" Extend to Compile-Time
Catching "Stack Overflow" Exceptions in Recursive C++ Functions
Link .So File to .Cpp File via G++ Compiling
How to Get the Mouse Position in a Console Program
Does C++ Contain the Entire C Language
Issue with Cin When Spaces Are Inputted, Using String Class
Member Fields, Order of Construction
When Extending a Padded Struct, Why Can't Extra Fields Be Placed in the Tail Padding
Two Phase Name Lookup for C++ Templates - Why
Removing Watermark Out of an Image Using Opencv
Initializing the Size of a C++ Vector
Do All Virtual Functions Need to Be Implemented in Derived Classes
Does Making a Struct Volatile Make All Its Members Volatile