http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55540
Bug #: 55540
Summary: The C++ literal -9223372036854775808 is misinterpreted
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: [email protected]
ReportedBy: [email protected]
The literal -9223372036854775808LL has type __int128 and says "warning: integer
constant is so large that it is unsigned [enabled by default]". Both of these
properties of that literal are incorrect, and, for good measure, they are
inconsistent with each other.
This is demonstrated in this C++11 code (for clarity -- a similar test in C++98
would show similar results):
#include <type_traits>
#include <limits>
// Using -9223372036854775807 instead works.
constexpr auto n = -9223372036854775808;
static_assert(n == std::numeric_limits<long long>::min(), "This test passes");
// This line assumes that long is 64-bit.
static_assert(std::is_same<decltype(n), const long>::value, "n has the wrong
type");
template<typename T>
struct what_is_t
{
static_assert(sizeof(T) != sizeof(T), "This is n's type");
};
what_is_t<decltype(n)> x;
which produces this output:
$ g++-trunk -std=gnu++0x big_negative_literal.cc
big_negative_literal.cc:6:21: warning: integer constant is so large that it is
unsigned [enabled by default]
constexpr auto n = -9223372036854775808;
^
big_negative_literal.cc:10:1: error: static assertion failed: n has the wrong
type
static_assert(std::is_same<decltype(n), const long>::value, "n has the wrong
type");
^
big_negative_literal.cc: In instantiation of ‘struct what_is_t<const
__int128>’:
big_negative_literal.cc:18:24: required from here
big_negative_literal.cc:15:3: error: static assertion failed: This is n's type
static_assert(sizeof(T) != sizeof(T), "This is n's type");
^
Quoting from [lex.icon]:
The type of an integer literal is the first of the corresponding list in Table
6 in which its value can be represented.
The first type with this property is long int (if 64-bits) or long long int
(otherwise).
The warning is totally incorrect: the literal may be large, but it both is and
should be *signed*.