为什么定义了sizeof实现的结果
Why is the result of sizeof implementation defined?
在C99中,§6.5.3.4:
2
sizeof
运算符产生其操作数的大小(以字节为单位),其可以是表达式或类型的带括号的名称。。。4结果的值由实现定义,其类型(无符号整数类型)是在
<stddef.h>
中定义的size_t
(以及其他标头)。
在C++14中,§5.3.3:
1
sizeof
运算符产生对象中的字节数其操作数的表示。。。sizeof的结果应用于任何另一个基本类型(3.9.1)是实现定义的。
唯一的保证值是sizeof(char)
、sizeof(unsigned char)
和sizeof(signed char)
,它们是一个。
然而,"对象表示中的字节数"对我来说似乎是铁一般的。例如,在C99§6.2.6.1中:
4存储在任何其他对象类型的非位字段对象中的值由n×CHAR_BIT位组成,其中n是对象的大小以字节为单位。。。
那么,如果它看起来定义得很好,为什么要定义它的实现呢?
你们中的许多人似乎误解了我的问题。我从未声称:
A) 类型的大小在所有系统上都有定义或相同,
B) 实现定义意味着它可以返回"随机值">
我得到的是n * CHAR_BITS
是一个固定的公式。公式本身不能在不同的实现之间更改。是的,int
可以是4个字节,也可以是8个字节。我明白了。但是在所有实现之间,该值必须为n * CHAR_BITS
。
sizeof
的结果是实现定义的,因为各种基本类型的大小都是实现定义。我们对C++中类型大小的唯一保证是
sizeof(char) = 1 and sizeof(char) <= sizeof(short) <= sizeof(int) <=
sizeof(long) <= sizeof(long long)
每种类型都有一个最小值,它必须支持C11[附件E(资料性)实施限制]/1
[…]显示的最小幅度应替换为具有相同符号的实施定义幅度。[…]
#define CHAR_BIT 8
#define CHAR_MAX UCHAR_MAX or SCHAR_MAX
#define CHAR_MIN 0 or SCHAR_MIN
#define INT_MAX +32767
#define INT_MIN -32767
#define LONG_MAX +2147483647
#define LONG_MIN -2147483647
#define LLONG_MAX +9223372036854775807
#define LLONG_MIN -9223372036854775807
#define MB_LEN_MAX 1
#define SCHAR_MAX +127
#define SCHAR_MIN -127
#define SHRT_MAX +32767
#define SHRT_MIN -32767
#define UCHAR_MAX 255
#define USHRT_MAX 65535
#define UINT_MAX 65535
#define ULONG_MAX 4294967295
#define ULLONG_MAX 18446744073709551615
因此,根据标准,int
必须能够存储一个可以存储在16位中的数字,但它可以更大,在当今的大多数系统中,它是32位。
我得到的是
n * CHAR_BITS
是一个固定的公式。公式本身不能在不同的实现之间更改。是的,int可以是4个字节,也可以是8个字节。我明白了。但在所有实现之间,值必须为n * CHAR_BITS
。
您是正确的,但n
根据C99§6.2.6.1定义为
其中
n
是该类型的对象的大小
emphasis mine
因此,公式可以是固定的,但n
不是固定的,并且在同一系统上的不同实现可以使用不同的n
值。
sizeof
的结果未定义实现。标准没有这么说;上面写着:
结果的值是实现定义的,[…]
这在语义上是不同的。sizeof
的结果是明确的:
[…]其操作数的大小(以字节为单位)[…]
此上下文中字节的位宽和非char
类型中的字节数都是实现定义的。
因为基本类型的大小是根据效率来定义的,而不是根据确切的位数来定义的。"int"必须是CPU能够有效操作的东西。对于大多数现代系统来说,这个数量是32位(或64位)。对于较旧的系统,它通常是16位。然而,如果存在35位的CPU,那么在这样的系统上的int将是35位。换句话说,C++不会应用惩罚来强制执行CPU可能根本不支持的位宽。
当然,有人可能会说,基本类型的奇异位宽的概念已经被历史所取代。我想不出有哪个现代CPU不支持8、16和32位的标准集(不同意这一说法,但至少要举个例子!),64位也很常见(如果硬件支持不可用,在软件中支持也没什么大不了的)。
可以说,C++语言已经不再使用可变位数的char;据我所知,u8"…"转换为char*,但unicode规范要求u8以8位编码。
如果8位的char的大小为1,那么32位的int的大小为4。如果16位的char的大小为1,那么32位的int的大小仅为2。如果这样的大小恰好是它们各自硬件的好选择,那么这两种情况在C++中都同样有效。
填充位是"未指定的",而不是"实现定义的"。
错误。非常非常错误。填充字节的值未指定。这里的意图是这些比特的值可以表示陷阱值,但不一定。
标准告诉sizeof
返回bytes * CHAR_BITS
,但不指定大小(除了exact-width类型)。一个类型占用的字节数是由实现定义的,因此sizeof
也必须是。
定义的实现描述为:
未指定的值,其中每个实现记录如何选择被制成
当您在以下示例中声明一个新变量时:
size_t a;
它将等于:
unsigned short int a; // unsigned short a
在32位计算机上,整数(int)的大小为4字节。短int的大小为2字节。
在C编程语言中,"size_t"是"sizeof()"运算符的返回类型。当你使用"sizeof()"运算符时,他会给你对象的大小。"sizeof()"的参数必须是l-value类型。元素(对象)的大小不能是负数,并且必须是整数。
- 为什么 MSVC _count_of实现将 0 添加到 sizeof 的结果中?
- OpenCV 混合模式实现:为什么看似等效的操作会产生不同的结果?
- libc++ 对 std::map/set::equal_range 的实现给出了意想不到的结果
- 微小加密算法实现会产生意想不到的结果
- 为什么在 C++ 中实现高斯勒让德算法没有产生结果
- 反向 Cuthill-McKee 算法:在 Matlab 和提升实现中具有无与伦比的结果
- 在我的C++链表实现中取消引用节点指针,给出意想不到的结果
- 在不同的平台/编译器上实现相同的浮点计算结果
- 为什么定义了sizeof实现的结果
- 特质实现给出了Clang和G 的不同结果,这是正确的
- C void*任何类型实现都会返回奇怪的结果
- Negamax C++实现给出了错误的结果
- 着色器中实现双精度cos()的结果是NaN,但在CPU上运行良好.出了什么问题
- C++,Lapack-Cholesky分解实现结果不准确
- 如何在c++中实现此结果?指向数组的数组
- 实现多个返回语句 c++ 时出现奇怪的结果
- 绕过虚拟模板功能以实现期望的结果
- C++成员函数结果缓存实现
- C++中合并排序实现的特殊行为,排序后的结果不应该在适当的位置
- HashTable实现的错误结果