我正在读Jans Gustedt的《现代C》.在一次关于如何确定数字文字类型的讨论中,他写到了将0xFFFFFFFF赋给signed变量的常见trap :

常见的错误是试图将十六进制常数赋给有符号的,并期望它表示负值.考虑这样的声明:int x= 0xFFFFFFFFF.这是在假设十六进制值具有相同的 以带符号值−1.On most architectures with 32-bit signed, this will be true (but not on all of them); but then nothing guarantees that the effective value +4294967295 is converted to the value −1表示的二进制表示形式.

我想要澄清这一粗体声明的含义.该声明是否仅仅说明了

  • 并非所有体系 struct 都有32位有符号整数,这一简单的事实意味着没有什么能保证从+4294967295到-1的转换?

或者,它是在试图说明这一点

  • 即使在32位有符号的体系 struct 上,也没有什么能保证有效值+4294967295转换为-1?

如果是后者,为什么会是这样?十六进制值与32位带符号体系 struct 上的-1具有相同的位表示这一事实难道不能保证转换在那里成功吗?

推荐答案

它是不是想表明这一点

  • 即使在32位有符号的体系 struct 上,也没有什么能保证有效值+4294967295转换为-1?

^这个.

如果按照规定,0xffffffff的类型是无符号的,则对类型为[signed]int的对象赋值会导致到该类型的转换.语言规范上写着:

当整数类型的值转换为除bool以外的另一个整数类型时,如果值 可以由新类型[...]表示. 否则,如果新类型是无符号的,则[...] 否则,新类型是有符号的,不能在其中表示值;either the result is implementation-defined or an implementation-defined signal is raised.

(C23 6.3.1.3)

该规范允许发出信号而不是转换过程,如果没有发出信号,则转换结果取决于实现.Gustedt描述的常见错误相当于假设无符号值的位模式将被重新解释为有符号int的位模式.有些实现实际上做到了这一点,但它们并不是必须做到的,而且还有其他看似合理的替代方案.例如,可能会将超出范围的值转换为目标类型的极值.

C++相关问答推荐

C限制限定符是否可以通过指针传递?

无效使用未定义类型'structsquare'?

是否有任何情况(特定类型/值),类型双关在所有符合标准的C实现中产生相同的行为?

如何判断宏参数是否为C语言中的整型文字

如何在C宏中确定 struct 中元素的类型?

如何在C客户端应用程序的ClientHello消息中添加自定义扩展?

如何创建一个C程序来存储5种动物的名字,并在用户 Select 其中任何一种动物时打印内存地址?

为什么数组的最后一个元素丢失了?

如何在提取的索引中分配空值?

在for循环中指向数组开头之前

如何将另一个数组添加到集合中,特别是字符串?

如何在VSCode中创建和使用我自己的C库?

在下面的C程序中,.Ap0是如何解释的?

为什么GCC 13没有显示正确的二进制表示法?

如何使用 VLA 语法使用 const 指针声明函数

为什么写入关闭管道会返回成功

C Makefile - 如何避免重复提及文件名

如何转义包含指令中的字符?

`void foo(int a[static 0]);` 有效吗?

初始化动态分配的布尔二维数组的最佳方法是什么?