Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should a 64-bit integer literal be represented in C++?

Tags:

c++

I'm puzzled by a difference in behavior between MSVC and clang for this code:

#include <iostream>
#include <cstdint>

int main() {
  int64_t wat = -2147483648;
  std::cout << "0x" << std::hex << wat << std::endl;

  return 0;
}

Visual Studio 2010, 2012, and 2013 (on Windows 7) all display:

0x80000000

But clang 503.0.40 (on OSX) displays:

0xffffffff80000000

What is the correct behavior according to the C++ standard? Should the literal be zero-extended or sign-extended to 64 bits?

I'm aware that int64_t wat = -2147483648LL; will lead to that same result on both compilers, but I wonder about the proper behavior without the literal suffix.

like image 262
Josh Peterson Avatar asked Sep 02 '14 14:09

Josh Peterson


People also ask

What is the 64-bit integer type?

A 64-bit signed integer. It has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). A 64-bit unsigned integer. It has a minimum value of 0 and a maximum value of (2^64)-1 (inclusive).

What is integer literal in C?

Integer literals are numbers that do not have a decimal point or an exponential part. They can be represented as: Decimal integer literals. Hexadecimal integer literals.

How do you declare a 64-bit integer in C++?

Microsoft C/C++ features support for sized integer types. You can declare 8-, 16-, 32-, or 64-bit integer variables by using the __intN type specifier, where N is 8, 16, 32, or 64.

How can I use 64-bit integer?

64-bit unsigned integer type is used to store only pozitiv whole number. 64-bit unsigned integer and his value range: from 0 to 18446744073709551615.


1 Answers

The type on the left of the initialization does not matter. The expression -2147483648 is interpreted by itself, independently.

Literal 2147483648 has no suffixes, which means that the compiler will first make an attempt to interpret it as an int value. On your platform int is apparently a 32-bit type. Value 2147483648 falls outside the range of signed 32-bit integer type. The compiler is required to use wider signed integer type to represent the value, if one is available (in the int, long int, long long int sequence, with the last one being formally available from C++11 on). But if no sufficiently wide signed integer type is available, the behavior is undefined

In MSVC historically long int has the same width as int, albeit 64-bit long long int is also supported in later versions of MSVC. However, even in VS2013 (which supports long long int) I get

warning C4146: unary minus operator applied to unsigned type, result still unsigned

in response to your initialization. This means that MSVC still sticks to archaic C89/90 rules of integer literal interpretation (where types were chosen from int, long int, unsigned long int sequence).

Note that MSVC is not officially a C++11 compiler. So formally it does not have to try long long int. Such type does not formally exist in pre-C++11 language. From that point of view, MSVC has no sufficiently large signed integer type to use in this case and the behavior is undefined. Within the freedom provided by undefined behavior, the use of C89/90 rules for integer literal interpretation is perfectly justifiable.

You might also take a look at this (-2147483648> 0) returns true in C++?

like image 88
AnT Avatar answered Oct 11 '22 11:10

AnT