【发布时间】:2021-02-28 08:15:58
【问题描述】:
以下代码是可以的,编译器不会产生任何警告。但是int怎么能存储unsigned int呢?
int c = UINT_MAX;
int d = 4294967295;
long int h = ULONG_MAX;
以下代码会产生警告,但为什么呢?这些基本上是上面long int h变量定义的扩展版本:
long int i = 18446744073709551615;
unsigned long int j = 18446744073709551615;
这是警告信息:
88308218/source.c:14:18: warning: integer constant is so large that it is
unsigned long int i = 18446744073709551615;
88308218/source.c:15:27: warning: integer constant is so large that it is
unsigned unsigned long int j = 18446744073709551615;
下面的代码是可以的。与上面int d的定义类似,只是后缀为u。似乎类型说明符比整数后缀弱。同样的问题也出现了关于在没有unsigned 类型的变量中存储的unsigned 值。
long int k = 18446744073709551615u;
示例源码如下:
#include <stdio.h>
#include <limits.h>
int main(void)
{
// how can unsigned val be stored in normal int without prop type (unsigned int)
// nor with suffix (u/U)
int c = UINT_MAX;
int d = 4294967295; // ok, same question with c
long int h = ULONG_MAX; // ok, same question with c
// the following produces warning, why? this is basically just expanded ver of h
long int i = 18446744073709551615;
long int j = 18446744073709551615u;
unsigned long int k = 18446744073709551615;
printf("%u\n", c);
printf("%u\n", d);
printf("%lu\n", h);
printf("%lu\n", i);
printf("%lu\n", j);
printf("%lu\n", k);
return 0;
}
编译结果:
$ gcc source.c
source.c: In function 'main':
source.c:12:16: warning: integer constant is so large that it is unsigned
12 | long int i = 18446744073709551615;
| ^~~~~~~~~~~~~~~~~~~~
source.c:14:25: warning: integer constant is so large that it is unsigned
14 | unsigned long int k = 18446744073709551615;
| ^~~~~~~~~~~~~~~~~~~~
【问题讨论】:
-
因为您似乎已经查找了对应于例如的
defineUINT_MAX,将其与您在此处的内容进行完全比较。差异与警告有很大关系。 -
始终启用和构建额外的警告。我通常使用
-Wall -Wextra -Wpedantic构建。其中一个包括警告选项-Woverflow,它会给你一个int d = 4294967295;的警告 -
1844 的“常量太大”警告的原因是该数字太大而无法适应编译器可用的任何有符号整数类型。另一方面,数字 4294... 确实 适合整数类型,特别是 64 位整数。所以编译器只是简单地通知你它会将 1844... 视为一个无符号数字,即使你没有告诉它(通过使用
u后缀)。 -
至于将
UINT_MAX分配给int类型:这将导致整数溢出,这是未定义的行为。换句话说,不要那样做。至于将 4294... 分配给int类型:这可能没问题,如果int恰好是 64 位或更大。否则,这是未定义的行为。
标签: c variable-assignment