2

If I have the following in a header file:

Foo.h

Foo
{
public:
  static const int BAR = 1234;
  ...
};

Do I also need to define the variable in the .cpp, e.g.:

Foo.cpp

const int Foo::BAR;

We have an issue where initializing a static in a header seems to work on MS compilers but with gcc on the Mac it seems to give linker errors.

Rob
  • 76,700
  • 56
  • 158
  • 197
  • possible duplicate of [C++ - defining static const integer members in class definition](http://stackoverflow.com/questions/3025997/c-defining-static-const-integer-members-in-class-definition) – Troubadour Aug 11 '10 at 15:47

4 Answers4

5

You need both the declaration and the definition, just as you've written them.

Since it is an integer, you can initialise it in the declaration as you've done, and the compiler should treat it as a compile-time constant when it can. But it still needs one (and only one) definition in a source file, or you'll get link errors when it can't be treated as a constant.

Apparently, Microsoft decided that the standard behaviour was too confusing, and "extended" the language to treat a declaration with an initialiser as a definition; see this issue. The result is that you get link errors (multiply defined symbols) if you also define the symbol correctly. You can get the standard behaviour by disabling language extensions (/Za).

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • If I include the second (.cpp) one then my app will not link under MSC and I get 'one or more multiply defined symbols found'. If I don't initialise the static in the header then it links. – Rob Aug 12 '10 at 08:00
1

The first fragment works for some environments but the definition really is required by some compilers and of course if you take the address of your constant.

If you don't like to have to touch header and body to introduce the constant, there still is the old enum-trick:

class A
{
   public:
       enum { someconstant=1234 };
};

makes someconstant available as a compile time constant without the need of a definition in the body.

Peter G.
  • 14,786
  • 7
  • 57
  • 75
  • 3
    The first fragment alone might work, if it's always treated as a compile-time constant. But it's a declaration, not a definition, and leaving out the definition is an error. You will get link errors if you ever try to take a reference or pointer to it, or if for some reason the compiler doesn't feel like treating it as a compile-time constant. – Mike Seymour Aug 11 '10 at 15:44
  • Thanks for pointing that out Mike. I stand corrected regarding the static const int definition. – Peter G. Aug 11 '10 at 17:42
0

Declarations should be done in the headers and initializations should be done on the .cpp

There's an interesting article about static member variables here.

karlphillip
  • 92,053
  • 36
  • 243
  • 426
0

The header file

Foo
{
public:
  static const int BAR;
  ...
};

The code file

const int Foo::BAR = 1234;
C.J.
  • 15,637
  • 9
  • 61
  • 77
  • Integer constant static members can be initialised where they're declared in the class definition. It's a good idea to do that, so they can be treated as compile-time constants when possible. – Mike Seymour Aug 11 '10 at 15:41