C语言中整数字面量的类型和~符号

21

我是一名C语言初学者,但是我对在C答案书中发现的以下示例感到困惑。

在您的系统上查找unsigned long long大小的一种方法是键入:

printf("%llu", (unsigned long long) ~0);

我不知道为什么这个语法能够工作?

在我的系统上,int是32位的,而long long是64位的。
我本来以为,由于0是整数类型的常量,~0会计算32位整数的否定值,然后由强制类型转换运算符转换为unsigned long long。这应该会得到232-1的结果。

不知何故,看起来~运算符已经知道它应该作用于64位?
编译器是否将这条指令解释为printf("%llu", ~(unsigned long long)0);?但这听起来不对,因为强制类型转换和~的优先级相同。

4个回答

14
不是 ~ 操作符,而是强制类型转换。按照标准规定进行整数转换的方式如下:
1. 如果将一个具有整数类型的值转换为其他整数类型(除 _Bool 之外),并且该值可以由新类型表示,则结果不变。 2. 否则,如果新类型为无符号型,则通过重复添加或减去新类型中可表示的最大值加一来转换该值,直到该值在新类型的范围内。 3. 否则,新类型为带符号型,而该值无法用它表示; 结果要么是实现定义的,要么引发实现定义的信号。
有符号 int 的值 ~0 在使用二进制补码表示负数值的系统上对应于 -1。 它不能由 unsigned long long 表示,因此第一个标点不适用。 第二个标点适用:新类型为无符号型,因此将 unsigned long long 的 MAX 加到 -1 上一次,使结果进入 unsigned long long 的范围。 这与将 -1 扩展为 64 位具有相同的效果。

1
~0的值取决于实现中的有符号表示。在除二进制补码以外的表示中,~0-1不同。 - ouah
那么(unsigned long long)~0u的预期行为会发生,对吗? - Quentin
@Quentin:这完全取决于你的期望。最好避免使用这个,因为它太依赖具体实现。 - Deduplicator

5
0int类型,而不是unsigned int类型。~0将因此(在使用二进制补码表示的机器上,这是现今所有机器都在使用的)为-1,而不是232-1。
假设有一个64位的unsigned long long,那么(unsigned long long)-1模264等于-1,即264-1。

这不应该是“实现定义”吗,而不是确定的(将有符号值强制转换为更长的无符号类型)?是的,在真正的普通2s补码机器上。在这种情况下,它可能会使用最自然可用的指令来扩展值,这可能不是符号扩展。 - JDługosz
@Wintermute你的意思是:0signed int类型而不是unsigned int类型...? - umlcat
@umlcat intsigned int - Wintermute

0

0 是一个 int

~0 仍然是一个 int,即值为-1

将一个 int 强制转换为 unsigned long long 只是为了与 printf 使用的转换符 llu 匹配。

但是,-1 扩展为无符号长整型的值应该为 4 字节 int 为 0xffffffff,8 字节 int 为 0xffffffffffffffff。


0
根据N1570委员会草案:

6.5.3.3 一元算术运算符

  1. ~ 运算符的结果是其(提升后的)操作数的按位补码(即,结果中的每个位仅在转换后的操作数中对应的位未设置时才设置)。对操作数执行整数提升,并且结果具有提升类型。如果提升类型是“无符号类型”,则表达式 ~E 等效于该类型中可表示的最大值减去 E。

§6.2.6.2 语言45:

(补码)。这些适用情况是实现定义的,与带符号位为1且所有值位为零(对于前两个)或带符号位和所有值位为1(对于补码)的值是陷阱表示还是正常值一样。在符号和大小以及补码的情况下,如果此表示是正常值,则称为负零。

因此,代码的行为是这样的:
printf("%llu", (unsigned long long) ~0);

在某些机器上,实现是定义不明确和未定义的 - 不符合预期 - 取决于机器中整数的内部表示。

根据第6.5.3.3节,编写代码的批准方式如下:

printf("%llu", (unsigned long long) ~0u);

此外,~0u 的类型是无符号整数,而您正在将其强制转换为 unsigned long long int,其格式字符串为 llu。要使用格式字符串%u打印~0u

要学习类型转换的基本概念,您可以阅读:C/C++中类型转换到底是什么?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接