Le 5 février 2012 00:03, Howard Hinnant <[email protected]> a écrit :
> On Feb 4, 2012, at 5:42 PM, Eli Friedman wrote: > > > On Sat, Feb 4, 2012 at 11:49 AM, Howard Hinnant <[email protected]> > wrote: > >> On Feb 4, 2012, at 2:29 PM, Eli Friedman wrote: > >> > >>> On Sat, Feb 4, 2012 at 10:50 AM, Howard Hinnant <[email protected]> > 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
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
