I know the standard is as follows:
The type of an integer literal depend on its value and notation:
But what about VC++?! It seems to be treating decimal, octal and hexadecimal the same and unsigned types are also allowed for decimals.
something like the following code:
cout << typeid(4294967295).name() << endl;
cout << typeid(4294967296).name() << endl;
cout << typeid(0xffffffff).name() << endl;
cout << typeid(0x100000000).name() << endl;
gives:
unsigned long
__int64
unsigned int
__int64
Is this expected and why it is different from the standard?
It appears that as far as your first result goes, VC++ still follows the rule from C89/90, which said (§ 6.1.3.2):
The type of an integer constant is the first of the corresponding list in which its value can be represented. Unsuffixed decimal:
int
,long int
,unsigned long int
; [...]
So, since 4294967295 can be represented as an unsigned long int
, that's what it's using.
In C++98/03, this is still permitted, but no longer required -- you're using a value larger than can be represented in an long int
, which gives undefined behavior (§ 2.13.1/2):
If it is decimal and has no suffix, it has the first of these types in which its value can be represented:
int
,long int
; if the value cannot be represented as a long int, the behavior is undefined.
[emphasis added]
C++11 adds long long int
to the list, so that's the type 4294967295
should become, but even in VC++ 2013 RC, it still follows the C89/90 standard in this respect and gives it type unsigned long int
.
Note that the the string produced by typeid
is implementation defined, so it doesn't have to correspond directly to the proper name of the type. If you use overloading, we can see that 0x100000000
and 4294967296
have type long long
though:
#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);
}
Result with VC++ 2008 and VC++ 2013 RC:
unsigned long
long long
unsigned int
long long
I don't have all the intervening versions installed, but given that 2008 and 2013 match, I think it's fair to guess that versions in between them act the same way as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.