1

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

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

long long unsigned ll =  0x123456789;

在编译时我得到

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

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

4

2 回答 2

6

将其更改为

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

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

在 C++03 中没有也没有任何价值long long,因此不能保证它可以工作,你依赖于扩展。您可能最好改用 C++11。

于 2012-02-27T16:41:21.167 回答
3

这里的事情是,很多人似乎在看像你这样的一行代码:

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

和原因“哦,类型是unsigned long long,所以值是unsigned long long并且它被分配”,但这不是 C 的工作方式。文字有自己的 type,这不依赖于它们被使用的上下文。整数文字的类型是int.

这与人们所做的谬误相同:

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

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

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

于 2012-02-27T17:11:58.437 回答