Patch for LWG issue #2145

Howard Hinnant hhinnant at apple.com
Tue Aug 20 20:38:51 PDT 2013


On Aug 20, 2013, at 11:12 PM, David Blaikie <dblaikie at gmail.com> wrote:

> On Tue, Aug 20, 2013 at 11:11 AM, Marshall Clow <mclow.lists at gmail.com> wrote:
>> http://cplusplus.github.io/LWG/lwg-defects.html#2145
>> 
>> Mark the constructor for std::error_category as inline and constexpr.
>> Leave the (existing, out-of-line, non-constexpr) in the dylib for compatibility with existing programs)
>> No tests, because I don't know how to test it (given that error_category is both an abstract class and has a user-defined destructor)
> 
> Curious - I haven't dealt with constexpr much, but could you explain
> further why this is untestable yet is a useful/meaningful change to
> make?

Sure, fair question.

It is legal to mark a constructor for a class as constexpr, even if that class can never be constructed as a constexpr variable:

struct X
{
     constexpr X() {}
     ~X();  //  disallow constexpr X here
};

One can legally:

X x;

but not:

constexpr X x;

So why mark X() constexpr?

<disclaimer>I'm learning this in real-time at nearly the same time you are.</disclaimer>

LWG 2145 discusses this a bit: http://cplusplus.github.io/LWG/lwg-defects.html#2145

Apparently if an X is constructed with static scope, if the constructor is marked as constexpr, then it will be constructed at compile time, even if the variable itself is not marked constexpr.  This has been used, for example, in the design of std::mutex:

   std::mutex m;

It is important that a global std::mutex be compile-time constructible so as to avoid race conditions during initialization code prior to main().  However you can't make mutexes constexpr:

   constexpr std::mutex m;  // worthless

because you have to mutate mutexes during program execution (lock them and unlock them).

Testing that X or std::mutex is actually constructed at compile time, and not during initialization prior to main() is challenging.  I'm nearly sure it is possible.  However I haven't yet succeeded in writing such a test, much less, installing such a test in the libc++ test suite.  My current best guess is that such a test would involve at least two translation units, which the current libc++ test suite is not capable of handling.

As I'm writing this, Marshall has also responded.  I agree with what Marshall is saying, and add my own words as well.

If anyone knows of a good way to write a test for the libc++ test suite that would test the presence/absence of a constexpr constructor for a non-literal type, that of course would be a welcome patch.  In the meantime, we stumble on. :-)

Howard




More information about the cfe-commits mailing list