0

I have a header file that defines 2 arrays

//GeometricPrimitives.h
#ifndef GEOMETRIC_PRIMITIVES_H
#define GEOMETRIC_PRIMITIVES_H
#include <gl/glew.h>

GLfloat cubeVerts[] = {
    //UP
     0.5, 0.5, -0.5,
     0.5, 0.5,  0.5,
    -0.5, 0.5,  0.5,
    -0.5, 0.5, -0.5,

    //DOWN
     0.5, -0.5, -0.5,
     0.5, -0.5,  0.5,
    -0.5, -0.5,  0.5,
    -0.5, -0.5, -0.5,

    //LEFT
    -0.5,  0.5, -0.5,
    -0.5,  0.5,  0.5,
    -0.5, -0.5,  0.5,
    -0.5, -0.5, -0.5,

    //RIGHT
    0.5,  0.5, -0.5,
    0.5,  0.5,  0.5,
    0.5, -0.5,  0.5,
    0.5, -0.5, -0.5,

    //FRONT
    -0.5,  0.5, 0.5,
     0.5,  0.5, 0.5,
     0.5, -0.5, 0.5,
    -0.5, -0.5, 0.5,

    //BACK
    -0.5,  0.5, -0.5,
     0.5,  0.5, -0.5,
     0.5, -0.5, -0.5,
    -0.5, -0.5, -0.5,
};

GLbyte cubeIndices[] = {
    1,2,3, 3,4,1,
    5,6,7, 7,8,5,
    9,10,11, 11,12,9,
    13,14,15, 15,16,13,
    17,18,19, 19,20,17,
    21,22,23, 23,24,21
};
#endif // !GEOMETRIC_PRIMITIVES_H

And file that includes it

//Mesh.h
    #pragma once
#include <gl/glew.h>
#include <SDL_opengl.h>
#include <gl/GLU.h>
#include "ShaderProgram.h"
#include "GeometricPrimitives.h"
class Mesh
{

public:
    Mesh();

    void bind(ShaderProgram* program);
    void init();
    void render();
private:
    GLuint vao;
    GLuint vbo;
    GLuint ibo;

    GLfloat* vertices;
    int verticesCount;
    GLbyte* indices;
    int indicesCount;
};

Mesh.h is included in GameObject.h which is included in main.cpp. When i compile i get error Error LNK2005 "float * cubeVerts" (?cubeVerts@@3PAMA) already defined in GameObject.obj

I read that this comes from the issue that the file gets added multiple times in different obj-s and then those get merged together giving the multiple definitions. How can i create this header with these static values and use them where i need them ?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Marko Taht
  • 1,448
  • 1
  • 20
  • 40

2 Answers2

2

As you suggested yourself, you can make your arrays static. In this way each translation unit will have the same copy of the same array but the arrays won't be visible outside of the translation units. So, the linker will be happy. But maybe you won't be happy as the same array will take twice memory (or maybe even more if you include it elsewhere).

So, another way is to put the definition of the array to GeometricPrimitives.cpp and leave only declarations in GeometricPrimitives.h. In this way the array will be created once and it will be used accross your application.

Also, don't forget to put const keyword if your arrays should be const.

rhaport
  • 540
  • 3
  • 11
  • +1 especially for `const`ness! I would add that, perhaps better, from C++17 these could be inline variables, so they can be defined in the header but will all refer to a single object in including translation units. However, what you said about moving the definition to the cpp could work too, if the values themselves don't really need to be in the header, which they probably don't. – underscore_d Jun 10 '20 at 12:33
  • do i need to declare them extern in .h file? – Marko Taht Jun 10 '20 at 12:44
  • @Marko yes, please do so. See more details here: https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files – rhaport Jun 10 '20 at 14:01
  • In what cases, and how, is `extern` helpful for this? – underscore_d Jun 10 '20 at 14:08
  • @underscore_d extern is used for declaration of the variable. Otherwise, it is immediately defined which may happen only once. – rhaport Jun 10 '20 at 16:29
1

Another solution if you can use C++17 or later would be to declare the arrays as inline variables. That way, they can be defined in a header that gets included in multiple translation units, but unlike static objects will all refer to the same single instance among all translation units.

As rhaport said, make sure also to make these const if they are meant to be read-only data, because you don't want to be able to accidentally mess up their values in one translation unit without another knowing about it.

underscore_d
  • 6,309
  • 3
  • 38
  • 64