How do you guarantee that only one instance of an error category will ever exist in the process?
If it's allowable to constexpr, I don't see how that's possible. I'd love to be corrected due to ignorance.
constexpr in this case doesn't change the number of instances that can exist in the process.
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. (My proposed additional changes is stop comparing by address, compare by category name via strcmp() instead. Yes this is much slower, but as you all may be gathering right now, low latency C++ isn't about minimum overhead, it's about predictable overhead. I don't care about spending a few predictable cycles here and there if I get more predictability)
The way to guarantee a single instance is to use the DLL/so runtime, and put the instance there.
Agreed. As I mentioned before, error categories are required to have a unique address in the process to work correctly.
MSVC's Immortalize is a directive to the VC runtime to ensure a single instance ever.
MS's _Immortalize is there to guarantee that the system_error machinery can be used during and after static destruction. That's why it's called "immortalize" - it makes the instance immortal, that is, makes sure its destructor is never invoked.
True. But it does more than that. If you link all your DLLs with the
static MSVC runtime so each gets a copy of a system_category
implementation, _Immortalize still ensures that only one instance ever
appears to exist in the process. So each error category always gets its
unique address in the process. At least, this is what I've been told.
You may not be aware, but last year I had an extended conversion with
STL over this because it was slowing Outcome down. STL took the view
that MSVC implements the standard correctly, and libstdc++ does not.
As annoyed as I was at the time about it, upon reflection STL is
correct. Adhering completely to the C++ standard requirements mandates
this behaviour. And yes, the standard is wrong on requiring this,