Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
448 views
in Technique[技术] by (71.8m points)

c++ - -9'223'372'036'854'775'808LL is unsigned

Since C++20 two's complement representation is the only representation allowed by the standard, with the guaranteed range from -2N-1 to +2N-1-1. So for a 64-bit signed integer type the range goes from -9'223'372'036'854'775'808 to 9'223'372'036'854'775'807. However, this code does not compile on Visual Studio (and neither on gcc)

int main()
{
    long long x{-9'223'372'036'854'775'808LL};
    // error C4146: unary minus operator applied to unsigned type, result still unsigned
    // error C2397: conversion from 'unsigned __int64' to '__int64' requires a narrowing conversion
}

Yet, if I replace the code with long long x{-9'223'372'036'854'775'807LL - 1} compiles just fine and x holds the correct value. What am I not getting here?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Without the LL suffix the type is taken as the first type in the list in the standard that fits. If you use the LL suffix then the value will specifically have type long long. However either way 9'223'372'036'854'775'808 is too large to fit in a long long (which is the largest signed type) so some compilers allow it as an extension to become unsigned long long, hence the warning. GCC and Clang do actually warn in that case. Contrary to many people's belief, there's no negative integer literal in C or C++. -9'223'372'036'854'775'808 is a unary minus applying to the integer 9'223'372'036'854'775'808

The type of the literal

The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used.

  • no suffix
  • decimal bases:
    • int
    • long int
    • long long int (since C++11)
  • binary, octal, or hexadecimal bases:
    • int
    • unsigned int
    • long int
    • unsigned long int
    • long long int (since C++11)
    • unsigned long long int (since C++11)
  • ...
  • suffix: ll or LL
  • decimal bases:
    • long long int (since C++11)
  • binary, octal, or hexadecimal bases
    • long long int
    • unsigned long long int (since C++11)
  • ...

If the value of the integer literal is too big to fit in any of the types allowed by suffix/base combination and the compiler supports extended integer types (such as __int128) the literal may be given the extended integer type -- otherwise the program is ill-formed.

In fact there are a lot of similar issues in the past where -2147483648 is also unsigned because at that time long long wasn't in the C and C++ standards and the largest type is unsigned long:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...