This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Use unsigned(-1) for lshift
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: Marc Glisse <marc dot glisse at inria dot fr>, gcc-patches at gcc dot gnu dot org, "Joseph S. Myers" <jsm at polyomino dot org dot uk>
- Date: Fri, 24 May 2013 10:44:47 +0200
- Subject: Re: Use unsigned(-1) for lshift
- References: <alpine dot DEB dot 2 dot 02 dot 1305232137430 dot 26811 at stedding dot saclay dot inria dot fr> <CAFiYyc3EXKqCdh=V4GSoG5_P5A-8RcL_OfM_my9OAVG-UiV+fg at mail dot gmail dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Fri, May 24, 2013 at 10:15:29AM +0200, Richard Biener wrote:
> On Thu, May 23, 2013 at 9:47 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> > Hello,
> >
> > this is a simple patch to reduce a bit the noise in PR57324 (undefined
> > behavior flagged by clang). I only handled some of the most obvious ones.
> > Passes bootstrap+testsuite on x86_64-linux-gnu.
>
> Hm, so ISO C99 says in 6.5.7/4 that (E1 << E2) "If E1 has signed type
> and nonnegative
> value, and E1 * 2^E2 is representable in the result type, then that is the
> resulting value; otherwise, the behavior is undefined."
>
> While seriously underspecified for signed negative values (always undefined?!
> or well-defined?!), I wonder why CLang requires
By strict reading of the standard, left shift of negative signed value by
any amount is undefined behavior in ISO C99 (no idea if it hasn't been
changed later on, Joseph?).
In C++98, in [expr.shift] it doesn't seem to mention E1 << E2 where E1 has
signed type at all, the is implementation defined sentence only in the
second paragraph, so one would expect that it applies to >> only.
C++11 [expr.shift] already has the wording of C99 (thus making it undefined
behavior?).
BTW, we have HOST_WIDE_INT_1 and HOST_WIDE_INT_C(X) macros, don't we want
also HOST_WIDE_INT_m1 for HOST_WIDE_INT_C(-1) and HOST_WIDE_INT_UC(X)
for HOST_WIDE_INT_C(X##U) (or whatever works for __int64) and
HOST_WIDE_INT_1U, HOST_WIDE_INT_m1U ? It would be more compact and could
make code more readable.
Jakub