1

If I do the following:

dConst.hpp

const int POWER_LEVEL = 9001;

genPower.hpp

#include "dConst.hpp"

#ifndef GENPOWER_HPP
#define GENPOWER_HPP

const int GENERATOR[1] = { POWER_LEVEL };

#endif

I end up getting linker errors for any code that utilizes the generator array constant.

However, if I switch the #include "dConst.hpp" with the code block:

#ifndef GENPOWER_HPP
#define GENPOWER_HPP

It works...

Am I misusing the power of the #ifndef?

  • This is valid, *const* declarations have internal linkage in C++. An include guard should never suppress linker errors. What compiler/linker generates this error? What does the linker error actually look like? – Hans Passant Nov 24 '13 at 19:56
  • @HansPassant I happened to be using the Visual Studio 2012 Compiler/Linker at the time – gate_engineer Nov 07 '14 at 07:04

2 Answers2

1

You are under-using the power of #ifndef.

Your dConst.hpp file needs include guards. Otherwise, it will cause problems (the exact problems you saw) if it is included from more than one file within a translation unit.

EDIT: I would also place your include guards in genPower.hpp at the top of the file, before your include statements.

NicholasM
  • 4,557
  • 1
  • 20
  • 47
1

Yes, definitely.

The point of include guards is to make sure your code doesn't get included twice - if you have some code in your header files that's not inside the include guard, if you include that header twice, you're defining everything outside the guards twice.

For a bit of a better idea of what's going on, your generated code looks something like this:

The #include basically just inserts the contents of the included file directly into the other file in place, meaning that your genPower.hpp looks like this (without the include guards in place properly, like you have originally in your question):

const int POWER_LEVEL = 9001;

#ifndef GENPOWER_HPP
#define GENPOWER_HPP

const int GENERATOR[1] = { POWER_LEVEL };

#endif

Therefore, every time you include that file, before the #ifndef gets reached, POWER_LEVEL gets defined. If you switch the POWER_LEVEL lines with the #ifndef/#define, every time you include this file, it will first CHECK if it's already been included (with the #ifndef - if it's already been included, the #define should have done its work) and ONLY THEN (once it's figured out this is the first time) will it define POWER_LEVEL.

Also, you almost definitely want include guards on your dConst.hpp as well - ALL headers should have include guards, and they should guard EVERYTHING in the header file. That's your mistake with #ifndef.