[cfe-commits] libc++ and const expr.

Matthieu Monrocq matthieu.monrocq at gmail.com
Sun Feb 5 04:11:54 PST 2012


Le 5 février 2012 00:03, Howard Hinnant <hhinnant at apple.com> a écrit :

> On Feb 4, 2012, at 5:42 PM, Eli Friedman wrote:
>
> > On Sat, Feb 4, 2012 at 11:49 AM, Howard Hinnant <hhinnant at apple.com>
> wrote:
> >> On Feb 4, 2012, at 2:29 PM, Eli Friedman wrote:
> >>
> >>> On Sat, Feb 4, 2012 at 10:50 AM, Howard Hinnant <hhinnant at apple.com>
> wrote:
> >>>> On Feb 4, 2012, at 1:19 PM, Howard Hinnant wrote:
> >>>>
> >>>>> On Feb 4, 2012, at 1:16 PM, Sebastian Redl wrote:
> >>>>>
> >>>>>>
> >>>>>> On 04.02.2012, at 19:06, Howard Hinnant wrote:
> >>>>>>
> >>>>>>> On Feb 4, 2012, at 12:52 PM, Howard Hinnant wrote:
> >>>>>>>
> >>>>>>>> On Feb 4, 2012, at 12:04 PM, Eli Friedman wrote:
> >>>>>>>>>
> >>>>>>>>> [expr.shift]p2: [...] if E1 has a signed type and non-negative
> value,
> >>>>>>>>> and E1×2E2 is representable in the result type, then that is the
> >>>>>>>>> resulting value; otherwise, the behavior is undefined.
> >>>>>>>>>
> >>>>>>>>> -Eli
> >>>>>>>>
> >>>>>>>> I see, you're point is that I've walked into undefined territory
> because I set the sign bit on the long long?  Does changing 1LL to 1ULL
> make the compiler happy?
> >>>>>>>
> >>>>>>> Another question:  Is there a motivation for giving the compile
> time behavior of these operations a different behavior than they would have
> at run time?
> >>>>>>
> >>>>>> The runtime behavior is undefined. Do you really want the compile
> time behavior to be the same?
> >>>>>>
> >>>>>> As a side note, I think the diagnostics here could still be
> improved.
> >>>>>>
> >>>>>> Sebastian
> >>>>>
> >>>>> It is undefined by the standards committee which has not had the
> willpower to abandon 1's complement hardware.  I believe it is well defined
> behavior on every platform we support (2's complement hardware).  I believe
> this compile time behavior is overly pedantic, does not reveal any
> programming error, and will only serve up busy work for clang's clients.
> >>>>>
> >>>>> Howard
> >>>>
> >>>> Just noticed:
> >>>>
> >>>> On Feb 3, 2012, at 7:33 PM, Richard Smith wrote:
> >>>>
> >>>>> constexpr:
> >>>>>  The recent support for potential constant expressions exposed a bug
> in the
> >>>>>  implementation of libstdc++4.6, where numeric_limits<int>::min() is
> defined
> >>>>>  as (int)1 << 31, which isn't a constant expression. Disable the
> 'constexpr
> >>>>>  function never produces a constant expression' error inside system
> headers
> >>>>>  to compensate.
> >>>>
> >>>> So it appears already that this is an issue wider than just libc++.
>  And I would be surprised if the issue isn't wide spread.  Just did a quick
> search of Boost and found this:
> >>>>
> >>>>      static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return
> 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); }
> >>>>
> >>>> Please reduce this to a pedantic warning and provide a way to turn it
> off locally even then.
> >>>
> >>> The problem is, this affects SFINAE...
> >>
> >> You are much more familiar with Chapter 14 than I am.  However in all
> places I'm aware, if the standard says that something is undefined
> behavior, the implementation can do anything it wants.  It can cause
> toilets to explode.  Or it can simply do what it believes its customers
> wanted in the first place.  I believe this is a case where we should do the
> latter.
> >
> > The issue is that with DR1313, "an operation that would have undefined
> > behavior" is not a constant expression.  Therefore, given a function
> > template like "template<bool b> void f(int (*a)[b ? 1 << 31]);", b ==
> > false is required to cause a substitution failure.
> >
> > -Eli
>
> Thank you for that link.  I will pursue this issue at the meeting next
> week and report back whatever the outcome is.
>
> As Richard reports that changing the 1LL to 1ULL fixes the issue, perhaps
> our customers who are caught by this will not be so irritated if they know
> the solution is this simple.  But I will still run this by the CWG to see
> if they would rather change this to be implementation defined behavior
> instead of undefined behavior.
>
> Howard
>
>
Sorry for barging in...

Still I find the issue of SFINAE worrying, for portability. Looking at the
example provided by Richard:

template<int n> auto f(int (&x)[n]) -> typename std::enable_if<(1 << n) <
kMaxTableSize, int>::type {
  // ...

If the CWG make it implementation defined and clang chooses to make it work
while gcc does not (I would be more worrid about MSVC I guess, since clang
and gcc are much closer), then we end up with a significant difference in
behavior between compilers. And those differences are always a pain to deal
with.

I honestly don't think that a lukewarm approach is going to cut it here,
either the CWG makes it well-defined or leaves it undefined and thus all
compilers accept or reject it (respectively). Otherwise we are in for a
world of hurt.

-- Matthieu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120205/9587ae28/attachment.html>


More information about the cfe-commits mailing list