The problem is that you are defining objects with an external link in the header file. It is expected that after including this header file in several translation units, you will get several definitions of the same object with external communication, which is an error.
The right way to do this depends on your intentions.
(1) You can put your definitions in the header file, but make sure they have an internal link.
In C, which requires 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 optional (because in C ++, const objects have an internal binding by default)
const double PI = 3.1415926535; const double PI_under_180 = 180.0f / PI; const double PI_over_180 = PI/180.0f;
(2) Or you can put simple non-information declarations in the header file and put the definitions in one (and only one) implementation file
Declarations in the header file must contain an explicit extern and not initialize
extern const double PI; extern const double PI_under_180; extern const double PI_over_180;
and definitions in one implementation file should look like this
const double PI = 3.1415926535; const double PI_under_180 = 180.0f / PI; const double PI_over_180 = PI/180.0f;
(explicit extern in definitions is optional if the above declarations precede definitions in the same translation unit).
Which method you choose depends on your intentions.
The first method simplifies the compiler to optimize the code, because it can see the actual value of the constant in each translation unit. But at the same time, conceptually, you get separate independent permanent objects in each translation unit. For example, &PI will evaluate a different address in each translation unit.
The second method creates truly global constants, i.e. unique permanent objects that are shared by the entire program. For example, &PI will evaluate the same address in each translation unit. But in this case, the compiler can see only the actual values ββin one and only one translation unit, which can complicate the optimization.