关于 sizeof 溢出的 C 标准 size_t
C standard regarding sizeof overflowing size_t
这是未定义的行为吗?标准相关部分就不多说了
size_t n = SIZE_MAX / sizeof(double) + 1;
size_t m = sizeof(double[n]);
C 标准并未明确声明 size_t
类型足以处理所有对象或类型的大小,尤其是对于未实际实例化的假设类型。
在C 2018 7.19 2中,标准说size_t
“是sizeof运算符结果的无符号整数类型”。这告诉我们关于 type size_t
但没有告诉我们计算过程中可能出现的 values。在 5.2.4 中,标准承认 C 实现必然有限制,并且它们必须在不同的点崩溃。
7.19 4 说“用于 size_t
和 ptrdiff_t
的类型不应具有大于 signed long int
的整数转换等级,除非实现支持足够大的对象以使其成为必要的。”这重申了我们希望 size_t
能够表示所有支持对象的大小,特别是因为它意味着对象的存在使得 size_t
能够表示它是“必要的”,但是它不是size_t
必须这样做的明确声明,也不适用于可以描述但不能实例化为对象的假设类型。
如果我们评估 n * sizeof(double)
,我们知道结果:6.2.5 9 说“涉及无符号操作数的计算永远不会溢出,因为无法由生成的无符号整数类型表示的结果被减少对比结果类型可以表示的最大值大 1 的数字取模。”然而,对于 sizeof(double[n])
,并不完全清楚这是否适用,因为尽管 n
是无符号的,但它不是 sizeof
的直接操作数,其中计算的结果无法表示发生。标准没有明确告诉我们这个sizeof
的结果会以同样的方式减少。
因此,此操作未包含在 C 标准中。
这是未定义的行为吗?标准相关部分就不多说了
size_t n = SIZE_MAX / sizeof(double) + 1;
size_t m = sizeof(double[n]);
C 标准并未明确声明 size_t
类型足以处理所有对象或类型的大小,尤其是对于未实际实例化的假设类型。
在C 2018 7.19 2中,标准说size_t
“是sizeof运算符结果的无符号整数类型”。这告诉我们关于 type size_t
但没有告诉我们计算过程中可能出现的 values。在 5.2.4 中,标准承认 C 实现必然有限制,并且它们必须在不同的点崩溃。
7.19 4 说“用于 size_t
和 ptrdiff_t
的类型不应具有大于 signed long int
的整数转换等级,除非实现支持足够大的对象以使其成为必要的。”这重申了我们希望 size_t
能够表示所有支持对象的大小,特别是因为它意味着对象的存在使得 size_t
能够表示它是“必要的”,但是它不是size_t
必须这样做的明确声明,也不适用于可以描述但不能实例化为对象的假设类型。
如果我们评估 n * sizeof(double)
,我们知道结果:6.2.5 9 说“涉及无符号操作数的计算永远不会溢出,因为无法由生成的无符号整数类型表示的结果被减少对比结果类型可以表示的最大值大 1 的数字取模。”然而,对于 sizeof(double[n])
,并不完全清楚这是否适用,因为尽管 n
是无符号的,但它不是 sizeof
的直接操作数,其中计算的结果无法表示发生。标准没有明确告诉我们这个sizeof
的结果会以同样的方式减少。
因此,此操作未包含在 C 标准中。