如何在C ++中表示64位整数文字?

时间:2014-09-02 14:36:56

标签: c++

我对这段代码的MSVC和clang之间的行为差​​异感到困惑:

#include <iostream>
#include <cstdint>

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

  return 0;
}

Visual Studio 2010,2012和2013(在Windows 7上)全部显示:

0x80000000

但是clang 503.0.40(在OSX上)显示:

0xffffffff80000000

根据C ++标准,正确的行为是什么?文字应该是零扩展还是符号扩展到64位?

我知道int64_t wat = -2147483648LL;会在两个编译器上产生相同的结果,但我想知道没有文字后缀的正确行为。

1 个答案:

答案 0 :(得分:13)

初始化左侧的类型无关紧要。表达式-2147483648由其自身独立解释。

Literal 2147483648没有后缀,这意味着编译器会首先尝试将其解释为int值。在您的平台上int显然是32位类型。值2147483648超出了带符号的32位整数类型的范围。编译器需要使用更宽的有符号整数类型来表示值(如果有的话)(在intlong intlong long int序列中,最后一个可以从C正式获得++ 11 on)。但是,如果没有足够宽的有符号整数类型可用,则行为未定义

在MSVC中,历史long int具有与int相同的宽度,尽管在更高版本的MSVC中也支持64位long long int。但是,即使在VS2013(支持long long int)中,我也会得到

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

响应您的初始化。这意味着MSVC仍然坚持使用古老的C89 / 90整数字面解释规则(其中类型选自intlong intunsigned long int序列)。

请注意,MSVC不是正式的C ++ 11编译器。所以正式地说它不必尝试long long int。这种类型在C ++ 11之前的语言中并不正式存在。从这个角度来看,MSVC在这种情况下没有足够大的有符号整数类型,并且行为是未定义的。在未定义行为提供的自由中,使用C89 / 90规则进行整数字面解释是完全合理的。

您还可以查看此(-2147483648> 0) returns true in C++?