[c++] Defining static const integer members in class definition

My understanding is that C++ allows static const members to be defined inside a class so long as it's an integer type.

Why, then, does the following code give me a linker error?

#include <algorithm>
#include <iostream>

class test
{
public:
    static const int N = 10;
};

int main()
{
    std::cout << test::N << "\n";
    std::min(9, test::N);
}

The error I get is:

test.cpp:(.text+0x130): undefined reference to `test::N'
collect2: ld returned 1 exit status

Interestingly, if I comment out the call to std::min, the code compiles and links just fine (even though test::N is also referenced on the previous line).

Any idea as to what's going on?

My compiler is gcc 4.4 on Linux.

This question is related to c++ static declaration definition

The answer is


C++ allows static const members to be defined inside a class

Nope, 3.1 §2 says:

A declaration is a definition unless it declares a function without specifying the function's body (8.4), it contains the extern specifier (7.1.1) or a linkage-specification (7.5) and neither an initializer nor a functionbody, it declares a static data member in a class definition (9.4), it is a class name declaration (9.1), it is an opaque-enum-declaration (7.2), or it is a typedef declaration (7.1.3), a using-declaration (7.3.3), or a using-directive (7.3.4).


Bjarne Stroustrup's example in his C++ FAQ suggests you are correct, and only need a definition if you take the address.

class AE {
    // ...
public:
    static const int c6 = 7;
    static const int c7 = 31;
};

const int AE::c7;   // definition

int f()
{
    const int* p1 = &AE::c6;    // error: c6 not an lvalue
    const int* p2 = &AE::c7;    // ok
    // ...
}

He says "You can take the address of a static member if (and only if) it has an out-of-class definition". Which suggests it would work otherwise. Maybe your min function invokes addresses somehow behind the scenes.


As of C++11 you can use:

static constexpr int N = 10;

This theoretically still requires you to define the constant in a .cpp file, but as long as you don't take the address of N it is very unlikely that any compiler implementation will produce an error ;).


Another way to do this, for integer types anyway, is to define constants as enums in the class:

class test
{
public:
    enum { N = 10 };
};

Here's another way to work around the problem:

std::min(9, int(test::N));

(I think Crazy Eddie's answer correctly describes why the problem exists.)


Not just int's. But you can't define the value in the class declaration. If you have:

class classname
{
    public:
       static int const N;
}

in the .h file then you must have:

int const classname::N = 10;

in the .cpp file.


Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to static

What is the equivalent of Java static methods in Kotlin? Creating a static class with no instances Static vs class functions/variables in Swift classes? Call static methods from regular ES6 class methods What is the difference between static func and class func in Swift? An object reference is required to access a non-static member Mocking static methods with Mockito @Autowired and static method The static keyword and its various uses in C++ Non-Static method cannot be referenced from a static context with methods and variables

Examples related to declaration

Component is part of the declaration of 2 modules What is the 'open' keyword in Swift? What’s the difference between “{}” and “[]” while declaring a JavaScript array? Getting error: ISO C++ forbids declaration of with no type What is an 'undeclared identifier' error and how do I fix it? Difference between int32, int, int32_t, int8 and int8_t forward declaration of a struct in C? How to initialize a vector in C++ Declare variable in SQLite and use it Initializing multiple variables to the same value in Java

Examples related to definition

"Multiple definition", "first defined here" errors SOAP vs REST (differences) Error with multiple definitions of function ReferenceError: variable is not defined C# Foreach statement does not contain public definition for GetEnumerator Add Auto-Increment ID to existing table? How to see the CREATE VIEW code for a view in PostgreSQL? Java: int[] array vs int array[] What is a web service endpoint? What is a "thread" (really)?