This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Unsure about a new warning in mainline


Gabriel Dos Reis <gdr@cs.tamu.edu> writes:

> Paolo Carlini <pcarlini@suse.de> writes:
> 
> [...]
> 
> | >Specifically, for PR 30465 "((T)1 << 31) - 1" is potentially undefined
> | >when  T is a 32-bit signed type, but well-defined if T is unsigned or
> | >wider than 32-bits.
> | >
> | FYI: this specific issue arises from std::numeric_limits<wchar_t> on
> | x86-linux: in particular from the __glibcxx_max macro at the beginning
> | of the header. Luckily, since we are dealing with template
> | specializations, the pragma is sufficient to suppress the warning, but
> | if you can figure out a better way to compute the max itself, just
> | speak...
> 
> I would like to understand this issue better and AVOID the pragma.
> If we need a pragma to make numeric_limits<wchar_t> not trigger
> warning then something is broken in either the warning machinery or
> numeric_limits<wchar_t> or both.  

When T is a signed 32-bit type, the expression ((T)1 << 31) is
undefined.  This is very clear in C99, section 6.5.7 (here I'm
assuming that C++ is similar):

    If E1 has a 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.

1 Ã 2^31 is not representatable in a 32-bit signed type.  The largest
number that can be represented in a 32-bit signed type is, of course,
1 Ã 2^31 - 1.  That is the number the above expression is trying to
compute, but operator precedence means that the actual result is
undefined.

One way to write this expression in a fully defined manner is:
    (((((T)1 << 30) - 1) << 1) + 1)

Another way is:
    ((T)(((unsigned T)1 << 31) - 1))

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]