2012-02-27 48 views
1

我遇到了一些我认为很奇怪的东西。测试程序在sparc上使用gcc为long long整数赋值solaris

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; 
}; 

输出为:

hello  
4  
8 

没有意外出现。 long int的大小为4个字节,而long long的大小为8个字节。 但是,当我改变它,以便长长分配

long long unsigned ll = 0x123456789; 

在编译的时候,我得到

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

现在这个相同的测试编译,如果我用强制的64位版本选项-m64。我做错了什么或者这是GCC中的错误?

回答

6

改变,要

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

不带后缀,字面是不是你的机器上最大unsigned long值更大,并且,根据C++ 03(但不包括C++ 11,其中有long long),是未定义的行为。这意味着任何事情都可能发生,包括编译时错误。

在C++ 03中没有long long也没有任何价值,所以它不能保证工作,而是依赖于扩展。您最好不要使用C++ 11来代替。

3

这里的事情是,许多人似乎看到像你的一行代码:

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

与理性“哦,类型为unsigned long long,所以价值unsigned long long,它被分配”,但这不仅仅是C的工作原理。文字有他们自己的类型,这并不取决于他们正在使用的上下文。整数文字的类型是int

这是相同的谬论当人们这样做:

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

思考“左边的类型是double,所以这应该分配0.3333333 ......”。这只是(再次!)而不是C如何工作。被分割的文字类型仍然是int,所以右侧的计算结果为0,然后转换为double并存储在one_third变量中。

出于某种原因,这种行为对许多人来说是非常不直观的,这就是为什么同一个问题有很多变种。

相关问题