Question

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

Certain matrices are used repeatedly in my program. I thought that I would define these in the "Matrix.h" header file, like so:

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

When I do this g++ complains that I redefined the constant in question. This happens because I include Matrix.h in two different source files. When the object files for these are compiled, both end up with a definition of the matrix above, causing the error message.

My question is how do I avoid this situation? I want a constant that is accessible to more than one file, but I don't know where to put it.

Was it helpful?

Solution

If you don't want to split it between a header and implementation file,

  1. Declare your constant static (or declare it in anonymous namespace) to make definition private. Linker will not complain, but it will result in multiple private copies across compilation units.

    static Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values);
    
  2. Make an inline function that returns the constant. Inline function definitions produce "weak" symbols in object file, so linker will eliminate duplicates and pick 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;
    }
    

OTHER TIPS

You avoid it by:

  • Declaring it extern in the header. A symbol can be declared any number of times.
  • Defining it in the implementation, only once.

just write your header file like this

#ifndef HEADER_FILE_NAME_H

#define HEADER_FILE_NAME_H

// your header file code

#endif

this will make sure that it won't get declared multiple times

Wrap header files (.h) in preprocessor conditionals to prevent them from being included in the compiler's 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's something related to the file to prevent more collisions, as this is just defining an empty preprocessor macro (which also ends up in the symbol table).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top