[cfe-commits] [Patch][Review] constexpr-ification of <limits> and random number generators

Howard Hinnant hhinnant at apple.com
Sun Apr 1 13:09:55 PDT 2012


On Apr 1, 2012, at 3:56 PM, Matthieu Monrocq wrote:

> 
> 
> Le 1 avril 2012 21:02, Howard Hinnant <hhinnant at apple.com> a écrit :
> 
> On Apr 1, 2012, at 2:53 PM, Jonathan Sauer wrote:
> 
> > Hello,
> >
> >>> the attached patch constexpr-ifies <limits> as specified in FDIS as well as removes the
> >>> workarounds in libc++'s random number generators due to missing constexpr (the workarounds
> >>> don't work when using a non-standard PRNG). The corresponding tests are modified as well.
> >>>
> >>> Please review and, if ok, commit.
> >>>
> >>>
> >>> With many thanks in advance,
> >>> Jonathan
> >>
> >> Thanks Jonathan.  I've been meaning to take care of this.  The current libc++ is a mess with respect to constexpr.
> >>
> >> One of the things I want to do is to allow libc++ to emulate correct behavior even when it is compiled in C++03 mode.  And I don't believe this patch will do this.
> >
> > No, it indeed does not. As libc++ currently uses said hack in <__config>, I simply worked from there.
> > I was not aware of the desired C++03 backwards compatibility. BTW, are new C++11 headers supposed to be
> > backwards compatible, too?
> 
> Most of them yes (random, forward_list, unordered....  I gave up on <tuple>).  Variadics on other things is very poorly supported in C++03.
> 
> >
> >> [...]
> >> This is just wrong, but taking it out is going to take a little more work.  I haven't nailed down exactly how we want to support both C++03 and C++11 mode, but I'm imagining something similar to the way we're handling noexcept:
> >>
> >> #ifndef _LIBCPP_HAS_NO_CONSTEXPR
> >> #define _CONSTEXPR_1 constexpr
> >> #define _CONSTEXPR_0 constexpr
> >> #else
> >> #define _CONSTEXPR_1 const
> >> #define _CONSTEXPR_0
> >> #endif
> >>
> >> (better macro names would be great!)
> >
> > How about _CONSTEXPR_FUNC for a constexpr function/method and _CONSTEXPR_STATIC for a constexpr static
> > member constant:
> >
> > #ifndef _LIBCPP_HAS_NO_CONSTEXPR
> > #define _CONSTEXPR_STATIC static constexpr
> > #define _CONSTEXPR_FUNC constexpr
> > #else
> > #define _CONSTEXPR_STATIC static const
> > #define _CONSTEXPR_FUNC
> > #endif
> >
> > I took the liberty of trying this out with <limits>; the patch is attached (I did not touch <random> this
> > time).
> 
> After looking over Richard's suggestion I'm toying with:
> 
> #ifdef _LIBCPP_HAS_NO_CONSTEXPR
> #define constexpr
> #endif
> 
> Then use
> 
> constexpr const int n = 5;
> 
> for variables, and
> 
> struct S {
>   constexpr S();
>   constexpr int f() const;
>   static constexpr const int bool = true;
> };
> 
> for functions and constructors.
> 
> Every single time I #define a keyword I live to regret it.  But I'm getting tempted again.  Anyone see the downside on this one?
> 
> Howard
> 
> 
> I do: it was not a keyword in C++03 so there might be code which actually used it as identifier... and your macro will not do well there.
> 
> I think it is better, if not so readable, to stick to identifiers reserved to the implementation (__constexpr ?), at least if it happens to collide with user code, it's the user code that needs to be fixed.

That's a good argument, thanks.  I guess I'm now favoring Richard's exact proposal:

#ifndef _LIBCPP_HAS_NO_CONSTEXPR
#define _LIBCPP_CONSTEXPR constexpr
#else
#define _LIBCPP_CONSTEXPR
#endif

Then use

_LIBCPP_CONSTEXPR const int n = 5;

for variables, and

struct S {
  _LIBCPP_CONSTEXPR S();
  _LIBCPP_CONSTEXPR int f() const;
};

for functions.

I like it better than Jonathan's, and my first _CONSTEXPR_1, _CONSTEXPR_0 because of the single macro that is either going to be constexpr or not.  The source code won't be as compact, but I find it more readable (though just a little too verbose).

Jonathan, I really appreciate you're work in <limits> and <random> and sorry about thrashing you around on this issue.  But I felt it important to hammer this out before we get too invested in the wrong strategy, as we already are with my ill-fated:

#ifdef _LIBCPP_HAS_NO_CONSTEXPR
#define constexpr const
#endif

Howard






More information about the cfe-commits mailing list