c - 结构的陷阱表示
问题描述
我想详细了解陷阱表示概念。定义很明确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
:
如果对象的存储值具有这样的表示形式并且由不具有字符类型的左值表达式读取,则行为未定义。
但
结构或联合对象的值绝不是陷阱表示,即使结构或联合对象的成员的值可能是陷阱表示。
我认为UB将由类似的东西引起
printf("Test.member = %lu\n", test.member);
但我不确定如何证明在这种情况下,表示member
是一个陷阱。
解决方案
member
没有陷阱表示,因为uint64_t
没有陷阱表示。
7.20.1.1 精确宽度整数类型
2 typedef 名称 uint N _t 指定宽度为N且无填充位的无符号整数类型。因此,uint24_t 表示这种无符号整数类型,其宽度正好为 24 位。
没有填充位。从以下部分我们了解到:
6.2.6.2 整数类型
1对于 unsigned char 以外的无符号整数类型,对象表示的位应分为两组:值位和填充位(后者不需要任何一个)。如果有 N 个值位,则每个位应表示 1 和 2 N - 1之间的 2 的不同幂,以便该类型的对象应能够 使用纯二进制表示表示从 0 到 2 N - 1 的值;这应称为值表示。未指定任何填充位的值。53)
注释 53 尽管不规范,但告诉我们这些填充位(如果存在)可用于捕获:
53)填充位的某些组合可能会产生陷阱表示,例如,如果一个填充位是奇偶校验位。无论如何,除了作为异常条件(例如溢出)的一部分之外,没有任何对有效值的算术运算可以生成陷阱表示,并且这不会发生在无符号类型中。填充位的所有其他组合都是由值位指定的值的替代对象表示。
而值位永远不能保存非法的模式。
所以你不能uint64_t
在一个格式良好的程序中产生一个陷阱表示。请注意,由于越界访问,您的程序具有 UB,但这不是由陷阱表示的可能性引起的。它本身是未定义的。
推荐阅读
- sql-server - 使用 bcp 日志文件时的 SQL Server 不是英文版
- excel - 如何将此代码转换为后期绑定,以便我的同事可以在 excel 2016 上使用该程序?
- php - 如果条件满足(购物车中的有限产品太多)Woocommerce 时重定向到页面的自定义功能
- blazor - 为什么我看不到对 DLL 的任何请求
- java - 读取模型上的轴突命令
- jenkins - 有没有办法在詹金斯开始执行管道之前验证管道文件
- reactjs - 我可以在反应中使用带有删除请求的 axios 发送表单数据吗?
- raspberry-pi - 树莓派 7 英寸触摸屏亮度控制 - 如何避免对 SD 卡的写入操作
- bash - 在 SQLPlus 中运行循环
- google-api - Google API 项目消失了