Niall Douglas wrote:
constexpr says that the compiler is allowed to assume that the instance in the current compilation unit is the sole one in the process. That lets it eliminate it. That's rather antithetical to the hard requirements in the standard. This is why I've discounted your LWG solution, without additional changes to permit multiple instances, I don't think your example solution can work.
`constexpr` can mean different things in different contexts. If you declare a constexpr variable of a literal type, yes, the compiler can eliminate it. That's not quite the case here though. extern const __system_category_impl __syscat; constexpr error_category const& system_category() { return __syscat; } Here `__syscat` is neither constexpr nor is it of a literal type (it has a virtual destructor.) system_category() is constexpr because it returns a known symbolic address, &__syscat, which can be compared for equality with other known symbolic addresses, and the comparison is constexpr, that is, its result is a compile-time constant expression. If you try to do something at compile time with the actual value to which system_category() returned a reference though, you'll fail; the only compile-time constant part of it is the address. If you then declare constexpr error_code ec( 0, system_category() ); now that would be a constexpr variable of a literal type, and the compiler is allowed to assume that it's the same even if it appears twice, and is allowed to eliminate it. But that's another thing entirely, and does not affect whether __syscat is unique. To make this even more complicated, constexpr has a third meaning; when put on a constructor, it enables static initialization. This is what makes it possible for __syscat to be defined in a manner so that it's initialized before anything else.