Frage

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?

War es hilfreich?

Lösung

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.

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top