在sparc solaris上使用gcc为long long整数赋值

时间:2012-02-27 15:41:09

标签: c++ gcc solaris sparc long-long

我遇到了一些我觉得很奇怪的事情。测试程序

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

如果我使用选项-m64强制进行64位构建,那么同样的测试编译。我做错了什么,或者这是GCC中的一个错误?

2 个答案:

答案 0 :(得分:6)

将其更改为

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

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

在C ++ 03中没有long long也没有价值,所以它不能保证工作,你依赖于扩展。你可能最好不要使用C ++ 11。

答案 1 :(得分: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变量中。

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