3

I'm working on a kernel and I want to make my static data member constexpr so I can have its values in an enum class. However, if I do so I get an undefined reference error. It only seems to work if I make it non-constexpr and initialize it outside of the class.

Working:

// terminal.hpp
class Terminal
{
    static uint32_t col_map[16];
};

// terminal.cpp
uint32_t Terminal::col_map[16] = {
    0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
    0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
    0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
    0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
};

Not working:

// terminal.hpp
class Terminal
{
    constexpr static uint32_t col_map[16] = {
        0x000000, 0x0000AA, 0x00AA00, 0x00AAAA,
        0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
        0x555555, 0x5555FF, 0x55FF55, 0x55FFFF,
        0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
    };

    enum class Color : uint32_t
    {
        Black = col_map[0],
        White = col_map[15]
    };  
};

Note that I tried to reproduce this on a regular compiler unsuccessfully so I think it has something to do with the kernel or cross compiler.

Linker error:

terminal.o: In function `Terminal::drawcolormap()':
terminal.cpp:(.text+0x6f): undefined reference to `Terminal::col_map'

I always run make clean; make.

1 Answers1

7

A static data member shall be defined outside the class if it is odr-used---period. There are no exceptions to this rule.

In the case that the data member is constexpr, it must also be initialized inside the class definition. However this does not abrogate the requirement to define it outside the class.

Correct code:

class Terminal
{
    constexpr static uint32_t col_map[16] = { /* ... */ };
    // ...
};
constexpr uint32_t Terminal::col_map[16]; // definition

It's counterintuitive, but that's just the way it is.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Actually that's not so counterintuitive, you are allowed to obtain the address of a variable contained in the array so you must provide a source file which can actually hold the static data. – Jack Sep 14 '14 at 04:59