【发布时间】:2018-12-23 08:27:12
【问题描述】:
我想详细了解陷阱表示的概念。定义很清楚Section 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,因为Section 6.2.6.1:
如果一个对象的存储值有这样的表示并被读取 通过没有字符类型的左值表达式, 行为未定义。
但是
结构或联合对象的值绝不是陷阱 表示,即使结构成员的值或 union 对象可能是一个陷阱表示。
我认为 UB 是由类似的东西引起的
printf("Test.member = %lu\n", test.member);
但我不确定如何证明在这种情况下member 的表示是一个陷阱。
【问题讨论】:
-
它是 UB,但不是因为任何可能的陷阱表示。相反,它是 UB,因为您越界访问内存,读取不属于您的内存。这发生在
//1。 -
只有当对象具有不用于值表示的位时,才可能使用陷阱表示。固定宽度的无符号整数类型使用它们的所有位来表示值。
-
@Someprogrammerdude 那么你能举一个结构成员的陷阱表示的例子吗?
-
@StoryTeller 但是
*test_ptr是lvalue,结构的值绝不是陷阱。为什么是这个UB?能给个参考吗? -
像
uint64_t member; ... printf("Test.member = %lu\n", test.member);这样的代码不必要地增加了混淆,因为"lu"肯定不是uint64_t的匹配打印说明符,因此printf("Test.member = %lu\n", test.member);UB 就在那里。最好使用"%" PRIu64编码。
标签: c struct language-lawyer