【问题标题】:Is size_t large enough to represent size of any type? [duplicate]size_t 是否足够大以表示任何类型的大小? [复制]
【发布时间】:2020-01-09 15:08:00
【问题描述】:

size_t 是否保证足够大以表示任何类型的大小?根据this参考:

size_t可以存储一个理论上可能的对象的最大尺寸 任何类型(包括数组)。

这通常是一个可靠的参考,但我在标准的相关部分中找不到任何证明或争议这一主张的内容。

【问题讨论】:

  • size_t 是 sizeof 运算符“返回”的类型,因此编译器应确保声明的对象适合它。至于动态分配的数组,我认为在技术上没有保证,但实际上,实现通常会将分配的大小限制为 ptrdiff_t,以防止 UB 在同一个对象中进行远距离指针减法。
  • @PSkocik 这就是为什么我用“语言律师”标记它
  • @PSkocik 鉴于malloc() 的大小参数是size_t,似乎很难想象一个实现能够动态分配大于size_t 可以表示的任何东西。如果您假设 calloc() 可以分配一个更大的对象,因为结果大小是两个 size_t 参数的乘积,这意味着必须有一个无符号整数类型能够表示大于 size_t 的大小并且更大type 应该被用作实际的size_t 类型。这似乎充其量是不正当的。
  • @AndrewHenle 是的
  • @PSkocik 好吧,一点挖掘表明“[t]he calloc 函数为 nmemb 对象数组分配空间”。根据 C 标准,数组是否被视为一个对象?如果不是,这是一个漏洞,允许calloc() 创建大于size_t 可以表示的数组。现在我们已经进入了语言律师理论的兔子洞......

标签: c language-lawyer size-t


【解决方案1】:

是的。 size_t 在 stddef.h 中定义,根据 sizeof 运算符 (6.5.3.4) 部分中的C99 standard

结果的值是实现定义的,其类型(无符号整数类型) 是size_t,在<stddef.h>(和其他头文件)中定义。

自从

sizeof 运算符产生其操作数的大小(以字节为单位)

并且它的返回类型是size_tsize_t必须能够包含任何类型的大小。

【讨论】:

  • 它在任何地方都没有说“它足够大”。具体来说,它没有说明“任何理论上可能的对象的最大尺寸”
  • @Ayxan 但是,它确实说“sizeof 运算符产生其操作数的大小(以字节为单位)”。因此,size_t 必须足够大以存储可以应用sizeof 的任何操作数的大小(否则sizeof 不会屈服于标准要求它产生的内容)。
  • @Angew 还有未声明的、动态分配的对象。在某种程度上可以想象(尽管实际上极不可能)你可以调用比 size_t 更多的内容,尽管参与如此深入的理论场景有点浪费时间,IMO。
  • @giusti 这就是为什么我的评论说calloc 而不是malloc
  • C 标准允许实现有限制,并允许运算符的理想结果超过类型中可表示的结果。虽然size_t 的目的是能够表示实现所支持的对象的大小,但这在 C 标准中没有明确说明。
【解决方案2】:

根据 C11 标准,6.5.3.4 The sizeof and _Alignof operators, paragraph 2

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

因此,sizeof 可用于获取任何对象的大小。

paragraph 5

两个运算符的结果值是实现定义的,其类型(无符号整数类型)是size_t,在<stddef.h>(和其他头文件)中定义。

size_t可以保存获取任意对象大小的结果。

所以,size_t 可以容纳任何对象的大小。

【讨论】:

  • 查看@PSkocik 对其他答案的评论
  • @Ayxan 并且能够calloc()size_t 更大的东西可以强烈地表示意味着存在能够表示更大的东西的类型。除非存在可以容纳大于 size_t 的大小的东西,否则如何创建已知大小大于 size_t 的东西?
  • 嗯,参考文献说“理论上可能的对象”,因此是“语言律师”标签。
  • C 标准允许实现有限制,并允许运算符的理想结果超过类型中可表示的结果。虽然size_t 的目的是能够表示实现所支持的对象的大小,但这在 C 标准中没有明确说明。
  • @AndrewHenle 我从您的其他一位 cmets 中看到您已经知道我的第二个观点,但要清楚,即使您认为这只是一个无意的措辞漏洞,我的第一个第一点是独立的。但是,经过进一步思考,我正在 +1-ing 这个答案,因为我认为所问的问题是正确的。 (问题是关于 任何类型的对象,而不是“C 标准可能允许您分配的任何连续内存区域”,而 arrays 是具有类型的单个对象, calloc-分配的内存也可以说不是“任何类型的”。)
猜你喜欢
  • 2013-11-11
  • 2011-08-25
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 2021-11-19
  • 1970-01-01
  • 2011-04-11
相关资源
最近更新 更多