3

One would think that this simple piece of code should compile easily:

#include <utility>

struct Q {
    static const int X = 0;
};

int main() {
    std::pair<int, int>(Q::X, 0);
    return 0;
}

However, when I compile this with g++ using the default settings (cygwin gcc 4.5.3) it throws a linker error at me:

undefined reference to `Q::X'

I'm totally stumped here -- MSVC compiles this just fine yet my gcc does not. (MinGW also works fine.)

Rufflewind
  • 8,545
  • 2
  • 35
  • 55

3 Answers3

3

The linker fails to find definition of Q::X.

This is probably because std::pair<> constructor takes arguments as references to const, and Q::X is an l-value, hence it requires an external definition of Q::X to be able to refer to that.

A portable fix:

int const Q::X;
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 1
    Well that's unfortunate; I have like a dozen of these `static const` definitions inside a traits(-like) class so it would be quite a burden to duplicate them outside. I think I'll just cast it to a value instead so it doesn't try to take a reference. Thanks for the help! – Rufflewind Jul 15 '13 at 09:35
1

You only declare X but you must also define it, which, for static definitions must happen outside the class

struct Q {
static const int X = 0;
};
int Q::X = 0;
ogni42
  • 1,232
  • 7
  • 11
1

@Maxim Yegorushkin (Beat me to it!) Here is a relevant link that might help.

But your problem is that the int is never externally defined. If X doesn't have to be const, you can initialize it outside the struct in a similar manner. The main reason is because X is static...

struct Q {
   static const int X;
};
int const Q::X = 0;

struct Q {
   static int X;
};
int Q::X = 0;
Community
  • 1
  • 1
Jonathan
  • 1,126
  • 10
  • 19