This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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