不能将-2147483648分配给long long类型的变量

时间:2014-01-22 22:25:32

标签: c

我正在编译下面的代码,由于某种原因,我不能将-2147483648分配给8字节长且已签名的变量。

long long x = -2147483648;

当我跨过这一行时,x的值是2147483648,MS Visual Studio中的'Watch'窗口显示x的类型是__int64。 sizeof(x)也返回8.

根据limit.h,签名长多的限制是:

#define LLONG_MAX     9223372036854775807i64       /* maximum signed long long int value */
#define LLONG_MIN   (-9223372036854775807i64 - 1)  /* minimum signed long long int value */

/* minimum signed 64 bit value */
#define _I64_MIN    (-9223372036854775807i64 - 1)
/* maximum signed 64 bit value */
#define _I64_MAX      9223372036854775807i64

我只是不明白!!!

有人可以对此有所了解吗?

5 个答案:

答案 0 :(得分:4)

如果没有LL,编译器似乎推断2147483648是32位unsigned long然后它应用-运算符。结果是0 - 2147483648。由于此值小于0且为unsigned long t,因此会添加4294967296,再次为2147483648。然后将此值分配给long long x

推荐:

long long x = -2147483648LL;
// or
long long x = -2147483647  - 1;

答案 1 :(得分:2)

尝试分配到-2147483648LL

请参阅整数常量here

答案 2 :(得分:2)

您的代码在我的GCC 4.6.3编译器上编译并执行正常,其中--std = c99。我怀疑你正在使用微软提供的相当无望的所谓C编译器。它显然不是很聪明。使用较长的长后缀(i64llLL)来欺骗它的行为。

有趣的是,MS C ++编译器也无法做到这一点:

#include <iostream>
int main()
{
    long long x = -2147483647;
    std::cout << x << std::endl;
    x = -2147483648;
    std::cout << x << std::endl;
    x = -2147483649;
    std::cout << x << std::endl;
    return 0;
}

<强>输出

-2147483647
2147483648
2147483647

我用VS2013的x86 C ++编译器编译了这个。

我从g ++ 4.6.3获得相同的输出。

所以我认为除此之外还有更多的东西。我希望比我更了解的人可以解释这一切。

答案 3 :(得分:1)

回答其他一些评论(对不起,因为我还没有足够的代表,所以无法回复每一条评论):

在C和C ++中,表达式的类型不依赖于其上下文。在这种情况下,-214743648的类型由语言规则定义,以后您将其分配给long long的事实不会影响这一点。

实际上这种做事方式使得语言比替代方案简单得多,这是首先吸引我使用C语言的一种方式。

在David Heffernan的例子中,

x = -2147483648;
std::cout << x << std::endl;     // gives 2147483648
x = -2147483649;
std::cout << x << std::endl;     // gives 2147483647

重要的是-符号不是整数文字的一部分。表达式2147483648是一个整数常量,其类型根据标准中的一组规则确定;然后将一元减号运算符应用于该值(不改变其类型)。

不幸的是,C90,C99,C ++ 98和C ++ 11对整数文字的类型都有不同的规则。此外,十进制常量的规则与十六进制或八进制常量的规则不同!您可以在相关的标准文档中查找它们。

如果您有32位整数,那么2147483648太大而不能成为int。在所有方言中,下一个可能的类型是long int。如果您还有32位long ints,则在C99或C ++ 11中它具有类型long long int。在C90或C ++ 98中,它具有类型unsigned long int。 (这些语言没有long long类型)。

回到David Heffernan的例子。 C ++ 98没有long long,因此要么使用C ++ 11编译器,要么使用Microsoft扩展。假设后者;谁知道他们决定对整数常量做什么,但如果他们保留了2147483648类型为unsigned long int的C ++ 98定义,那就可以解释结果。

答案 4 :(得分:0)

原来我只需要这样写:

long long x = -2147483648i64;

为什么编译器无法解决问题。我已经拼出了这个类型,为什么我必须把'i64'放在数字???

之后