Search code examples
c++include-guards

C++ Include guards


I know this been asked a number of times but no answers seem to solve this.

I have two files.

Main.cpp

#include <irrlicht\irrlicht.h>

#include <vector>
#include <string> 
#include <iostream>

#include "Scene.h"
#include "Camera.h"
#include "Gui.h"

irr::IrrlichtDevice* device;
irr::video::IVideoDriver* driver;

int main() {
 device = irr::createDevice(irr::video::EDT_SOFTWARE, irr::core::dimension2d<irr::u32>(640, 480), 16, false, false, false, 0);

if (!device)
    return 1;

device->setWindowCaption(L"NeoTrap");
driver = device->getVideoDriver();
sceneManager = device->getSceneManager();
GUIEnvironment = device->getGUIEnvironment();

//Testing
Mesh* ground = new Mesh();
//Testing

while (device->run()) {
    driver->beginScene(true, true, irr::video::SColor(255, 120, 102, 136));

    sceneManager->drawAll();
    GUIEnvironment->drawAll();

    driver->endScene();
}

device->drop();
return 0;
}

Scene.h

#ifndef _SCENE_HEADER_
#define _SCENE_HEADER_

irr::scene::ISceneManager* sceneManager; 

struct Mesh {
public:
Mesh();

private:
};

class Scene {
public:
Scene();

private:

};

#endif

What I am trying to do is declared a variable in Scene.h and define it from within the main function. I am not sure if I don't understand include guards, but I am getting weird errors:

'irr': is not a class or namespace name syntax error: missing ';' before '*' missing type specifier - int assumed. Note: C++ does not support default-int

but when I move the following line back in the Main.cpp file

irr::scene::ISceneManager* sceneManager;

the program compile. When am I not able to declare it in scene.h and set the value from the main function?


Solution

  • It's best to not declare variables in headers. It ends badly far more often than not because every file that includes the header will make their very own sceneManager. When the linker comes along to put the program together it may find dozens of sceneManagers all with an equal claim to being the real sceneManager, throw its hands up in disgust, and spray error messages all over the console.

    In scene.h add

    #include <irrlicht\irrlicht.h>
    

    up at the top to declare all the bits and bobs of irrlicht so that they are available in scene.h.

    Then change

    irr::scene::ISceneManager* sceneManager; 
    

    to

    extern irr::scene::ISceneManager* sceneManager; 
    

    extern tells the compiler that sceneManager exists and storage will be allocated somewhere else. The compiler smiles and carries on, leaving sorting out where the one, true sceneManager is to the linker.

    Finally, put

    irr::scene::ISceneManager* sceneManager; 
    

    in Main.cpp to allocate storage so that the linker has a sceneManager to find.

    Documentation on extern

    Recomended reading: When to use extern in C++