Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 结构的陷阱表示_C_Struct_Language Lawyer - Fatal编程技术网

C 结构的陷阱表示

C 结构的陷阱表示,c,struct,language-lawyer,C,Struct,Language Lawyer,我想详细了解陷阱表示的概念。定义非常清楚第3.19.4节: 不需要表示对象值的对象表示 类型 好的,我想通过一些例子来尝试一下 struct test_t{ uint64_t member; }; struct test_t *test_ptr = malloc(sizeof(uint32_t)); struct test_t = *test_ptr; //1 我不认为/1会导致UB,因为第6.2.6.1节: 如果对象的存储值具有这样的表示并被读取 通过不具有字符类型的左值表达式 行

我想详细了解陷阱表示的概念。定义非常清楚
第3.19.4节

不需要表示对象值的对象表示 类型

好的,我想通过一些例子来尝试一下

struct test_t{
    uint64_t member;
};

struct test_t *test_ptr = malloc(sizeof(uint32_t));
struct test_t = *test_ptr; //1
我不认为
/1
会导致UB,因为
第6.2.6.1节

如果对象的存储值具有这样的表示并被读取 通过不具有字符类型的左值表达式 行为是未定义的

但是

结构或联合对象的值决不是陷阱 表示,即使结构或构件的值 联合对象可以是陷阱表示

我认为UB将由以下原因引起

printf("Test.member = %lu\n", test.member);

但是我不确定如何证明在这种情况下,
成员的表示是一个陷阱。

成员
没有陷阱表示,因为
uint64\t
没有陷阱表示

7.20.1.1精确宽度整数类型

typedef名称uintN\u t指定无符号整数类型 宽度为N且无填充位。因此,uint24_t表示这样的 宽度正好为24位的无符号整数类型

没有填充位。我们从以下部分了解到:

6.2.6.2整数类型

对于无符号字符以外的无符号整数类型,位 对象的表示形式应分为两组:值 位和填充位(不需要任何后者)。如果有 如果是N值位,则每个位应代表2的不同幂 介于1和2N-1之间,因此该类型的对象应 能够使用 纯二进制表示;这应被称为价值 代表性。任何填充位的值都是 未指明(第53段)

其中注释53尽管不规范,但告诉我们这些填充位(如果存在)可用于陷阱:

填充位的某些组合可能会产生陷阱 表示,例如,如果一个填充位是奇偶校验位。 无论如何,对有效值的算术运算都不能生成 陷阱表示,而不是作为例外条件的一部分 例如溢出,而这不能发生在无符号类型中。全部的 填充位的其他组合是可选对象 由值位指定的值的表示形式

而值位永远不能保存非法的模式


因此,您无法在格式良好的程序中生成
uint64\t
的陷阱表示。请注意,您的程序由于越界访问而具有UB,但这不是由陷阱表示的可能性引起的。它本身是未定义的。

它是UB,但不是因为任何可能的陷阱表示。取而代之的是UB,因为你访问了超出范围的内存,你读取了不属于你的内存。这种情况发生在
//1
上。只有当对象具有不用于值表示的位时,才能使用陷阱表示。固定宽度无符号整数类型使用其所有位表示值。@某个编程人员,那么您能给出一个结构成员陷阱表示的示例吗?@StoryTeller,但
*test_ptr
是一个
左值
,结构的值从来都不是陷阱。这是为什么?您能提供一些参考吗?代码如uint64\u t member。。。printf(“Test.member=%lu\n”,Test.member)
不必要地增加了混淆,因为
的“lu”
不一定是
uint64\u t
的匹配打印说明符,因此使得
printf(“Test.member=%lu\n”,Test.member)UB就在那里。最好使用
“%”PRIu64
进行编码。现在使用的唯一具有陷阱表示的类型是浮点数和枚举类型。我误解了陷阱表示的概念。。。谢谢