简体   繁体   中英

assigning a value to a long long integers using gcc on sparc solaris

I came across something that I think rather strange. The test program

int main(int argc, char* argv[])
{
    cout<<"hello"<<endl;
    long unsigned l = 0x12345678;
    long long unsigned ll =  0x12345678;
    cout<<sizeof(l)<<endl;
    cout<<sizeof(ll)<<endl;
};

output is:

hello    
4    
8

No surprises there. The long int has a size of 4 bytes and the long long has a size of 8 bytes. However, when I change it so that the long long is assigned

long long unsigned ll =  0x123456789;

at compile time I get

error: integer constant is too large for "long" type

Now this same test does compile if I force a 64 bit build using the option -m64 . Am I doing something wrong or is this a bug in GCC?

Change that to

long long unsigned ll = 0x123456789ULL; // notice the suffix

Without the suffix, the literal is bigger than the maximum unsigned long value on your machine, and that, according to C++03 (but not C++11, which has long long ), is undefined behavior. This means that anything can happen, including a compile-time error.

It's also worth nothing that there's no long long in C++03, so it's not guaranteed to work, you're relying on an extension. You'd probably better be off using C++11 instead.

The thing here is that many people seem to look at a line of code like your:

unsigned long long ll = 0x123456789;   /* ANTI-PATTERN! Don't do this! */

and reason "oh, the type is unsigned long long , so the value is unsigned long long and it gets assigned", but that's just not how C works. Literals have their own type , that doesn't depend on the context in which they're being used. And the type of integer literals is int .

This is the same fallacy as when folks do:

const double one_third = 1 / 3;   /* ANTI-PATTERN! Don't do this! */

Thinking "the type on the left is double , so this should assign 0.3333333...". That's just (again!) not how C works. The types of the literals being divided is still int , so the right hand side evaluates to exactly 0, which is then converted to double and stored in the one_third variable.

For some reason, this behavior is deeply non-intuitive to many people, which is why there are many variants of the same question.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM