Red*_*Red 4 c++ visual-c++ c++11
我知道标准如下:
整数文字的类型取决于其值和符号:
但是VC++怎么样?!它似乎将十进制,八进制和十六进制视为相同,并且小数也允许使用无符号类型.
类似下面的代码:
cout << typeid(4294967295).name() << endl;
cout << typeid(4294967296).name() << endl;
cout << typeid(0xffffffff).name() << endl;
cout << typeid(0x100000000).name() << endl;
Run Code Online (Sandbox Code Playgroud)
得到:
unsigned long
__int64
unsigned int
__int64
Run Code Online (Sandbox Code Playgroud)
这是预期的,为什么它与标准不同?
看来,就你的第一个结果而言,VC++仍然遵循C89/90的规则,其中说(第6.1.3.2节):
整数常量的类型是相应列表中可以表示其值的第一个.无后缀十进制:
int
,long int
,unsigned long int
,[...]
因此,因为4294967295可以表示为a unsigned long int
,所以它正在使用它.
在C++ 98/03中,仍然允许这样做,但不再需要 - 您使用的值大于可以在a中表示的值long int
,这给出了未定义的行为(第2.13.1/2节):
如果它是十进制且没有后缀,则它具有这些类型中的第一个,其值可以表示为:
int
,long int
; 如果该值不能表示为long int,则行为未定义.
[强调补充]
C++ 11添加long long int
到列表中,因此4294967295
应该成为类型,但即使在VC++ 2013 RC中,它仍然遵循C89/90标准,并给出了类型unsigned long int
.
请注意,生成的字符串typeid
是实现定义的,因此它不必直接对应于该类型的正确名称.如果您使用重载,我们可以看到0x100000000
并4294967296
具有类型long long
:
#include <iostream>
void f(unsigned long){
std::cout << "unsigned long\n";
}
void f(long long) {
std::cout << "long long\n";
}
void f(unsigned long long) {
std::cout << "unsigned long long\n";
}
void f(unsigned) {
std::cout << "unsigned int\n";
}
int main(){
f(4294967295);
f(4294967296);
f(0xffffffff);
f(0x100000000);
}
Run Code Online (Sandbox Code Playgroud)
VC++ 2008和VC++ 2013 RC的结果:
unsigned long
long long
unsigned int
long long
Run Code Online (Sandbox Code Playgroud)
我没有安装所有介入版本,但考虑到2008年和2013年的匹配,我认为可以猜测它们之间的版本也采用相同的方式.