我遇到了一些我觉得很奇怪的事情。测试程序
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中的一个错误?
答案 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
变量中。
出于某种原因,这种行为对许多人来说是非常不直观的,这就是为什么同一个问题有很多变种。