I'm puzzled by a difference in behavior between MSVC and clang for this code:
我对这个代码的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, and 2013 (on Windows 7) all display:
Visual Studio 2010,2012和2013(在Windows 7上)全部显示:
0x80000000
But clang 503.0.40 (on OSX) displays:
但是clang 503.0.40(在OSX上)显示:
0xffffffff80000000
What is the correct behavior according to the C++ standard? Should the literal be zero-extended or sign-extended to 64 bits?
根据C ++标准,正确的行为是什么?文字应该是零扩展还是符号扩展到64位?
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.
我知道int64_t wat = -2147483648LL;将在两个编译器上产生相同的结果,但我想知道没有文字后缀的正确行为。
1 个解决方案
#1
13
The type on the left of the initialization does not matter. The expression -2147483648
is interpreted by itself, independently.
初始化左侧的类型无关紧要。表达式-2147483648独立地由其自身解释。
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
Literal 2147483648没有后缀,这意味着编译器将首先尝试将其解释为int值。在您的平台上,int显然是32位类型。值2147483648超出了带符号的32位整数类型的范围。编译器需要使用更宽的有符号整数类型来表示值(如果有的话)(在int,long int,long long int序列中,最后一个可以从C ++ 11正式获得)。但是,如果没有足够宽的有符号整数类型可用,则行为未定义
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
在MSVC中,历史上long int具有与int相同的宽度,尽管在更高版本的MSVC中也支持64位长long int。但是,即使在VS2013(支持long long int)中,我也能得到
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).
响应你的初始化。这意味着MSVC仍然坚持使用古老的C89 / 90整数文字解释规则(其中类型选自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.
请注意,MSVC不是正式的C ++ 11编译器。所以正式地说它不必尝试很长的int。这种类型在C ++ 11之前的语言中并不正式存在。从这个角度来看,在这种情况下,MSVC没有足够大的有符号整数类型,并且行为未定义。在未定义行为提供的*中,使用C89 / 90规则进行整数字面解释是完全合理的。
You might also take a look at this (-2147483648> 0) returns true in C++?
您可能还会看一下这个(-2147483648> 0)在C ++中返回true?
#1
13
The type on the left of the initialization does not matter. The expression -2147483648
is interpreted by itself, independently.
初始化左侧的类型无关紧要。表达式-2147483648独立地由其自身解释。
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
Literal 2147483648没有后缀,这意味着编译器将首先尝试将其解释为int值。在您的平台上,int显然是32位类型。值2147483648超出了带符号的32位整数类型的范围。编译器需要使用更宽的有符号整数类型来表示值(如果有的话)(在int,long int,long long int序列中,最后一个可以从C ++ 11正式获得)。但是,如果没有足够宽的有符号整数类型可用,则行为未定义
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
在MSVC中,历史上long int具有与int相同的宽度,尽管在更高版本的MSVC中也支持64位长long int。但是,即使在VS2013(支持long long int)中,我也能得到
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).
响应你的初始化。这意味着MSVC仍然坚持使用古老的C89 / 90整数文字解释规则(其中类型选自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.
请注意,MSVC不是正式的C ++ 11编译器。所以正式地说它不必尝试很长的int。这种类型在C ++ 11之前的语言中并不正式存在。从这个角度来看,在这种情况下,MSVC没有足够大的有符号整数类型,并且行为未定义。在未定义行为提供的*中,使用C89 / 90规则进行整数字面解释是完全合理的。
You might also take a look at this (-2147483648> 0) returns true in C++?
您可能还会看一下这个(-2147483648> 0)在C ++中返回true?