Q:

using static const member to initialize another static const in c++

I face the following problem :
I have a Color class, that for the purpose of this question, reduces to :
// Color.h
struct Color {
    int r,g,b;
    Color() : r(0), g(0), b(0) {}
    Color(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {}
    static const Color Red;
    static const Color Magenta;
};

// Color.cpp
#include "Color.h"
const Color Color::Red (255,0,0);
const Color Color::Magenta (255,0,255);

I.e, I want to use the class name as a scope for some predefined colors.
Now in a user file in a global scope I do :
//user.cpp
#include "Color.h"
static const Color colors[2] = { Color::Red, Color::Magenta };

And when I use colors[i] I see that they were filled with 0s.
I looked it up and saw that the empty constructor is first called (that doesn't make sense for a reason soon to reveal), and then I changed the empty c'tor to :
    Color() : r(200), g(200), b(200) {}

And got the same result.
I tried to define the colors as constexpr like this :
    static constexpr Color Red (255, 0, 0);

But it said :
    expected identifier before numeric constant
And then like this :
    static constexpr Color Red = {255, 0, 0};

And like this :
    static constexpr Color Red = Color(255, 0, 0);

But then the compilation failed because "'Color' was not declared in this scope", and "Red has incomplete type" (really?)
So now it really doesn't make sense that the empty c'tor was used, but rather this whole memory was initialized with 0.
In runtime I can use the static const Colors and it works.
I this behaviour even well-defined? Does it depend on compilation / linkage order?
How do I work around it?
Thanks

A:

You are running into the Static Initialization Order Fiasco.  It sounds like your colors array is getting initialized before the Red and Magenta objects are.
One solution is the Construct On First Use Idiom:
// Color.h
struct Color {
    int r,g,b;
    Color() : r(0), g(0), b(0) {}
    Color(int r_, int g_, int b_) : r(r_), g(g_), b(b_) {}
    static const Color& Red();
    static const Color& Magenta();
};

// Color.cpp
#include "Color.h"
const Color& Color::Red()
{ static const Color red(255,0,0); return red; }
const Color& Color::Magenta()
{ static const Color magenta(255,0,255); return magenta; }

//user.cpp
#include "Color.h"
static const Color colors[2] = { Color::Red(), Color::Magenta() };

