How to avoid accidental reuse of global constants in C ++?

I have a template matrix class class defined in the header called "Matrix.h".

My program uses several matrices repeatedly. I thought that I would define them in the header file "Matrix.h", for example:

const Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values); 

When I do this, g ++ complains that I have overridden this constant. This is because I include Matrix.h in two different source files. When the object files for them are compiled, both end with the definition of the above matrix, causing an error message.

My question is: how can I avoid this situation? I want a constant available for several files, but I don’t know where to put it.

+4
source share
4 answers

If you do not want to split it between the header and the implementation file,

  • Declare a static constant (or declare it in an anonymous namespace) to make the definition private. Linker will not complain, but this will result in several private copies in compilation units.

     static Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values); 
  • Create an inline function that returns a constant. Inline function definitions produce β€œweak” characters in the object file, so the linker removes duplicates and selects one.

     inline const Matrix<GLfloat>& GET_B_SPLINE_TO_BEZIER_MATRIX() { const static Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values); return B_SPLINE_TO_BEZIER_MATRIX; } 
+6
source

You are avoiding this:

  • Ad extern in title. A symbol can be declared as many times as necessary.
  • Define it in implementation, only once.
+8
source

just write your header file as follows

#ifndef HEADER_FILE_NAME_H

#define HEADER_FILE_NAME_H

// code of your header file

#endif

this ensures that it will not be announced several times

0
source

Close the header files (.h) in the preprocessor conditional expressions so that they are not included in the compiler symbol table twice:

 #ifndef HEADER_NAME #define HEADER_NAME // code... #endif//HEADER_NAME 

HEADER_NAME can really be anything, but it’s best to make sure that it has something to do with the file in order to prevent more conflicts, as it simply defines an empty preprocessor macro (which also falls into the symbol table).

0
source

All Articles