Rob*_*min 6 c language-lawyer c11 c17
在 C11 [C11_N1570]和 C17 [C17_N2176]的最新草案中,我找不到以下内容的证明(我相信这是众所周知的):
sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
有人可以向我推荐特定部分吗?
我知道C++11 的这个回复。回复的第二部分讨论了C,但只涉及了values的范围。它并不能证明字体大小之间的比例。
非常感谢所有参与寻找答案的人。\n大多数回复都分享了我已经学到的东西,但有些评论提供了非常有趣的见解。
\n下面我将总结一下我到目前为止所学到的内容(供我自己将来参考)。
看起来 C (截至 C17 [C17_N2176]的最新草案)并不能保证\
n \n(与C++sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
相反)。
下面是我自己对 C对整数类型的保证的解释/总结(抱歉,如果我的术语不够严格)。
\n这个主题让我摆脱了同一类型的多个别名([C17_N2176],6.2.5/4 带括号的句子指的是 6.7.2/2,感谢 @MM 的参考)。
\n一个字节中的位数是特定于实现的,并且是>= 8。它是由CHAR_BIT标识符确定的。
\n5.2.4.2.1/1 整数类型的大小<limits.h>
\n\n它们的实现定义值的大小(绝对值)应等于或大于所示的值,并具有相同的符号。
\n
\n\n非位字段 ( byte )的最小对象的位数
\n
\nCHAR_BIT 8
下面的文字假设字节是8位(请记住,在字节具有不同位数的实现中)。
\nsizeof([[un]signed] char)sizeof(char)、sizeof(unsigned char)、sizeof(signed char)、 均为 1 字节。
\n6.5.3.4/2sizeof和_Alignof运算符
\n\n运算
\nsizeof符产生大小(以字节为单位)其操作数的
6.5.3.4/4:
\n\n\n当
\nsizeof应用于类型为 、 或 的操作char数unsigned char时signed char,\n(或其限定版本)的操作数时,结果为 1。
对象可能不使用所有位来存储值
\n对象表示具有值位,可能具有填充位,并且对于有符号类型,只有一个符号位(6.2.6.2/1/2 整数类型)。\nE.g 。变量的大小可以为 4 个字节,但只能使用 2 个最低有效字节来存储值\n(对象表示只有 16 个值位),类似于bool至少有 1 个值位,并且所有其他位是填充位。
值的范围和类型的大小(或值位数)之间的对应关系是有争议的。
\n一方面 @eric-postpischil 指的是 3.19/1:
\n\n价值
\n
\n解释为具有特定类型时对象内容的精确含义
这给人的印象是每个值都有唯一的位表示(位模式)。
\n另一方面@language-lawyer 指出
\n\n\n不同的值不必由不同的位模式表示。因此,可以有比可能的位模式更多的值。
\n
\n\n当标准和委员会回应(CR)之间存在矛盾时,委员会回应由实施者选择。
\n
\n\n根据 DR260 委员会的回应,对象表示中的位模式不能唯一确定该值。\n不同的值可以由相同的位模式表示。
\nCHAR_BIT所以我认为== 8的实现和sizeof(int)是可能的。
\n\n我没有声称一个对象有多个值同时具有多个值
\n
@语言律师的陈述给人的印象是,可能在不同时刻的多个值(例如,,),\n可以对应于变量值位的相同位模式(例如,5)\ 23n 。如果这是真的,那么除(参见上面的“The”部分)之外的整数类型可以具有任何字节大小\n(它们必须至少有一个值位,这阻止它们具有字节大小(严格来说偏执) ,\n这会导致至少一个字节的大小),\n以及整个值范围(由-10xFFFF[[un]signed] charsizeof([[un]signed] char)>= 10<limits.h>,见下文)可以对应于“至少一个值位”。
总而言之,sizeof(short)、sizeof(int)、 、之间sizeof(long)的关系sizeof(long long) 可以是任意的
n(其中任何一个,以字节大小计,都可以大于或等于任何其他关系。同样,严格来说,有点偏执)。
什么似乎没有争议
\n没有提到的是 6.2.6.2/1/2 整数类型:
\n\n对于无符号整数类型..如果有\nN 个值位,则每个位应表示 1 到 2^(N-1) 之间的 2 的不同幂,因此该类型的对象\n应能够表示从 0 到2^N - 1 使用纯二进制表示..
\n
\n\n对于有符号整数类型.. 作为值位的每个位应与相应无符号类型的对象表示中的相同位具有相同的值..
\n
这让我相信每个值位都会为对象的整体值添加一个唯一的值。例如,最低有效值位(我将其称为值位编号 0)(无论它位于字节中的哪个位置)添加一个值2^0 == 1,并且没有任何其他值位添加该值,即值被唯一地添加。\n值位编号 1(同样,无论其在字节中的位置如何,但位置与任何其他值位的位置不同)唯一地添加值2^1 == 2。
\n这两个值位加起来就是 1 + 2 == 3 的总绝对值。
在这里,我不会深入探讨它们是否在设置为 1时、清除为 0或这些值的组合时添加值。\n在下面的文本中,我假设它们在设置为 1 时添加值。
\n为了以防万一,我还将引用 6.2.6.2/2 整数类型:
\n\n\n如果符号位为 1,则应通过以下方式之一修改该值:
\n
\n...
\n\xe2\x80\x94 符号位的值为 -(2^M) (二\xe2\x80 \x99s 补码);
前面的 6.2.6.2/2 中已经提到 M 是有符号类型中的值位数。
\n因此,如果我们讨论的是具有 7 个值位和 1 个符号位的 8 位有符号值,则符号位如果设置为 1,则会添加 -(2^M) == -(2^7) 的值==-128。
之前我考虑过一个示例,其中两个最低有效值位的总和等于总体绝对值 3。\n对于具有 7 个值位的 8 位有符号值,将符号位设置为 1,总体有符号值将是 - 128 + 3 == -125。
\n例如,该值的位模式为 0x83(符号位设置为 1 (0x80),两个最低有效值位设置为 1 (0x03),并且如果满足以下条件,则两个值位都会添加到总体值中:在二进制补码表示中设置为 1,而不是清除为 0)。
这一观察使我认为,很可能,对象中的值范围和值位数之间存在一一对应关系-每个值都有唯一的值位模式,并且每种值位模式唯一地映射到单个值。
\n(我意识到这个中间结论仍然不够严格或错误或未涵盖某些情况)
5.2.4.2.1/1 整数类型的大小<limits.h>:
\n重要句子:
\n\n它们的实现定义值应等于或大于所示的值(绝对值),并具有相同的符号。
\n
然后:
\n\n\n\n
SHRT_MIN -32767 // -(2^15 - 1)
\nSHRT_MAX +32767 // 2^15 - 1
\nUSHRT_MAX 65535 // 2^16 - 1
这告诉我
\n至少short int有15 个值位(请参见上面的 ),即至少 2 个字节(如果字节是 8 位,请参见上面的“字节中的位数”)。\n至少有16 个值位(上面),即至少 2 个字节。SHRT_MINSHRT_MAXunsigned short intUSHRT_MAX
继续该逻辑(参见 5.2.4.2.1/1):
\n至少int有15 个值位(参见, ),即至少 2 个字节。\n至少有16 个值位(参见),即至少 2 个字节。\n至少有31 个值位(参见、),即至少 4 个字节。\n至少有32 个值位(参见),即至少 4 个字节。\n至少有63 个值位(参见、),即至少 8 个字节。\n至少有64 个值位(参见),即至少 8 个字节。INT_MININT_MAXunsigned intUINT_MAXlong intLONG_MINLONG_MAXunsigned long intULONG_MAXlong long intLLONG_MINLLONG_MAXunsigned long long intULLONG_MAX
这向我证明:
\n < { , , , }1 == sizeof(char)中的任何一个。sizeof(short)sizeof(int)sizeof(long)sizeof(long long)
sizeof(int)6.2.5/5 类型
\n\n\n“普通”
\nint对象具有执行环境体系结构建议的自然大小(足够大以包含header 中定义的INT_MIN范围内的任何值)。INT_MAX<limits.h>
这向我证明:
\nsizeof(int) == 4在 32 位架构上(如果字节是 8 位),
\nsizeof(int) == 8在 64 位架构上(如果字节是 8 位)。
sizeof(unsigned T)6.2.5/6 类型
\n\n\n对于每个有符号整数类型,都有一个对应的(但不同的)无符号整数类型(用关键字指定
\nunsigned),它使用相同的存储量(包括符号信息)并具有相同的对齐要求。
这向我证明:
\nsizeof(unsigned T) == sizoef(signed T)。
6.2.5/8 类型
\n\n\n对于任何两个具有相同符号和不同整数转换等级的整数类型(参见6.3.1.1),具有较小整数转换等级的类型的值的范围是另一个类型的值的子范围。
\n
(参见下面 6.3.1.1 的讨论)
\n我假设值的子范围可以包含与该范围相同或更少数量的值。\n即 转换排名较小的类型可以具有与转换排名较高的类型相同或更少的值。
6.3.1.1/1 布尔值、字符和整数
\n\n\n\xe2\x80\x94 的等级
\nlong long int应大于 的等级long int, 的等级应大于 的等级int, 的等级应大于 的等级short int, 的等级应大于 的等级signed char。
\n\xe2\x80\x94 任何无符号整数类型的等级应等于相应的有符号整数类型(如果有)的等级。
\n\xe2\x80\x94 的等级_Bool应小于所有其他标准整数类型的等级。
\n\xe2\x80\x94 任何枚举类型的等级应等于兼容整数类型的等级(参见 6.7.2.2)。
这告诉我:
\n range_of_values(bool) <= range_of_values(signed char) <= range_of_values(short int) <= range_of_values(int) <= range_of_values(long int) <= range_of_values(long long int)。
\n对于无符号类型,值范围之间的关系是相同的。
这为值位数建立了相同的关系这为类型中的
\n但仍然没有证明这些类型的对象的字节大小之间存在相同的关系。
\n即 C(自[C17_N2176]起)不保证以下语句(与 C++ 相对):
\nsizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)