0

I've spent like 2 days researching to avoid the multiple definition of some arrays and I found #ifdef and bla bla. So I tried to test my program with that #ifdef and it doesn't do anything, the debugger is still saying that there are multiple definitions. My programs works like this.

enter image description here

Of course there are multiple definition, but I need to make this like I've shown you in the pic... I think this is a compiler problem or something related about compiler.

PD: I suppose you don't need any code to resolve my problem, if you need then I'll share.

GameObject.h:

#ifndef GameObject_H
#define GameObject_H

#pragma once

float cube[] =
{
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f
};

float Space3D_X[] =
{
    0.0f, 0.0f, -100,
    0.0f, 0.0f, 100
};

float Space3D_Z[] =
{
    -100.0f, 0.0f, 0.0f,
    100.0f, 0.0f, 0.0f
};

float Space3D_Y[] =
{
    0.0f, -100.0f, 0.0f,
    0.0f, 100.0f, 0.0f
};

typedef struct GameObject
{
    int ID, parent;
    Vector3 position;
    Quaternion rotation;
};

struct GameObject GameObjects[65536];

typedef struct Entity
{
    static int GameObjectsCount;
    int CreateCube (Vector3 _position, Quaternion _rotation, int _parent);
    void SetGameObjectParent (int _gameObject, int _parent);
};

Entity Entity_t;

#endif // GAMEOBJECT_H
tony perez
  • 61
  • 1
  • 6
  • 3
    Don't put definitions into header files. – Kerrek SB May 21 '15 at 16:52
  • 1
    The usual way is to check whether a given token is defined or not with `ifndef` then define it, write all the code and end with the `endif`. – a_pradhan May 21 '15 at 16:55
  • 1
    possible duplicate of [Why aren't my compile guards preventing multiple definition inclusions?](http://stackoverflow.com/questions/249701/why-arent-my-compile-guards-preventing-multiple-definition-inclusions) – Algo May 21 '15 at 16:57
  • I told you I already did that way, but check the code anyway. – tony perez May 21 '15 at 17:00
  • 2
    Re the comment by @KerrekSB , *Don't put definitions into header files*. What Kerrek meant was, well, don't put definitions into header files. Your `float cube[] = ...` is a **definition**. Don't do that in a header file. It will cause a heap of trouble. – David Hammen May 21 '15 at 17:02

2 Answers2

6

Put the definitions into the cpp file. If you put them to the header, they will be defined in every cpp file which includes the header.

GameObject.h

#ifndef GAMEOBJECT_H
#define GAMEOBJECT_H

extern float cube[];
...
typedef struct GameObject
{
    int ID, parent;
    Vector3 position;
    Quaternion rotation;
};

extern GameObject GameObjects[65536];
...
#endif

GameObject.cpp

#include "GameObject.h"

float cube[] = {...};
...
GameObject GameObjects[65536];
simon
  • 1,210
  • 12
  • 26
3

Header guards only deal with including a header more than once in a single translation unit (directly or indirectly).

For example, given something like typedef x y; you cannot repeat that same typedef again at the same scope:

typedef x y; // fine
typedef x y; // Not allowed -- `y` is already defined

Including the same header more than once (typically not both directly) could lead to this sort of problem, and that's what header guards prevent.

Header guards do not help at all with anything that stems from including the same header in more than one source file. The obvious example is when you've defined an object in a header file. Then when you link more than one source file that includes that header, you end up with link errors from multiple definitions of that object.

The cure for this problem is to write your code so the definition of that object occurs exactly once in one source file. The header then contains only a declaration of that object. For example:

source.cpp:

int x[1234];

source.h:

extern int x[];

This makes x visible, so code in other source files can access x, but only defines it in one place, so you don't violate the one definition rule, causing the linker to complain about multiple definitions.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • This is a great answer, but it makes me wonder about the OP's use case - they want to make this definition of their cube coordinates to be available to multiple different bits of code - perhaps it's a bounding box definition used both by enemy collision detection and maybe by the character intersecting with the ground - I'm just making this up to illustrate my question: how do you approach having these kinds of shared definitions that are available to multiple, possibly unrelated bits of code or classes? – Tom Auger Feb 03 '22 at 14:39
  • @TomAuger: About as shown in the answer. You'd create a header that defines the type and declares the objects, something like: `using Plane = /* however you want to define a plane */; extern Plane ground;`, then a single `.cpp` file that includes that header, and defines the plane for the ground: `#include "ground.h"\nPlane ground { /* initializers here */ };`, and include that header in any other file that needs to refer to the ground (and when you build, compile and link that .cpp file along with the rest). – Jerry Coffin Feb 06 '22 at 20:19