具有陷阱表示的自定义 uint16_t 的大小是多少?

问题描述 投票:0回答:2

以下C标准的所有章节号都来自这个特定的C11草案版本

段。 C11 第 3.19.4 节第 1 条规定:

陷阱表示

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

段。 C11 第 6.2.6.2 节第 1 条规定:

对于unsigned char以外的无符号整数类型,对象的位 表示应分为两组:值位和填充位(需要 不是后者中的任何一个)。 ...

段。 C11 第 6.5.3.4 节第 2 条规定:

sizeof 运算符产生其操作数的大小(以字节为单位),这可能是一个 表达式或类型的括号名称。大小由类型决定 操作数

假设地,假设我设计了一个 CPU 架构(浪费地)使用三个字节(24 位)来存储

uint16_t
(又名
short
)。这个浪费
uint16_t
的范围还是[0, 65535]。它的最后两个字节是一个普通的
uint16_t
,第一个字节是为所有可能的陷阱表示保留的。

为了简单起见,假设

uint16_t
只有在第一个字节是
0000 0000
时才有效;如果第一个字节不是
uint16_t
.
,则 
0000 0000

未初始化(因此是陷阱表示)

问题是,对于我浪费的一个变量

short

uint16_t a = 123;

sizeof
的预期结果是什么?:

sizeof a;

更重要的是,应该使用C标准的哪一部分的哪一段来支持预期的结果?

c language-lawyer sizeof
2个回答
0
投票

sizeof 运算符的结果不依赖于存储在对象中的值。

正如你自己写的

sizeof 运算符产生其操作数的大小(以字节为单位),这 可以是表达式或带括号的类型名称。大小是 由操作数的类型决定

所以根据你的描述

假设,假设我设计了一个 CPU 架构 (浪费)使用三个字节

sizeof 运算符将返回 3,尽管类型名称会使用户感到困惑。

更真实的情况是结构。它们的数据成员之间可以有很多填充,并且考虑这些填充以确定必须为结构类型的对象分配多少内存。

还要考虑指针运算。如果你有一个像

这样的数组
uint16_t a[2];

那么表达式

a + 1
必须指向数组的第二个元素。表达式的计算方式类似于
( char * )a + sizeof( uint16_t )
。如果
sizeof( uint16_t )
不等于3,你会得到一个不正确的值。


0
投票

有两种可能的结果。 1 或 3。

在你设计的“奇废”系统中,我们不知道用于存储

char
的字节数。如果您决定为
char
使用 3 个字节,则答案为 1。如果您决定为
char
使用 1 个字节,则答案为 3.

一般答案是:

(bytes used for storing wasteful-uint16) / (bytes used for storing char)
© www.soinside.com 2019 - 2024. All rights reserved.