【问题标题】:Why is rsize_t defined?为什么要定义 rsize_t?
【发布时间】:2016-02-09 20:19:39
【问题描述】:

我发现strncpy_s()VS2013下被定义为

errno_t __cdecl strncpy_s
(
  _Out_writes_z_(_SizeInBytes) char * _Dst, 
  _In_ rsize_t _SizeInBytes, 
  _In_reads_or_z_(_MaxCount) const char * _Src, 
  _In_ rsize_t _MaxCount
);

rsize_t 是:

typedef size_t rsize_t;

我认为这是 Visual Studio 的一个技巧。但是,我发现这个函数在这个page上定义如下

errno_t strncpy_s
(
  char *restrict dest,
  rsize_t destsz,
  const char *restrict src, 
  rsize_t count
); 

为什么在这里定义rsize_t

如果在这里使用size_t 会怎样?

有什么特殊情况可以使用这个rsize_t

【问题讨论】:

  • 这不是特定于视觉工作室的typedef 吗?它似乎没有出现在我的头文件中,也似乎没有出现在我的标准草稿中。
  • 您可能(或可能不会)在Do you use the TR-24731 "safe" functions? 中找到一些有用的信息,至少,如果您担心可移植性,您应该注意其中突出显示的一些问题。

标签: c++ size-t tr24731


【解决方案1】:

您在 Microsoft 的 C++ 标准库中遇到过它,但它实际上来自 C.C 11,准确地说,这意味着它在技术上不是 C++ 的一部分。

C 11 标准,附录 K 介绍了所有 _s 函数和相应的 typedef,包括 rsize_t。还有一个“最大值”宏RSIZE_MAX,对于典型应用来说足够大,但小于该类型的实际最大值。当rsize_t 类型的值超过RSIZE_MAX 时,安全函数什么都不做并报告错误。

这个想法是为了避免缓冲区溢出崩溃和由无效大小引起的类似错误,通常是由于使用负值的大小造成的。在 2 的补码有符号值表示(最常见的一种)中,当被视为无符号时,负数对应于 非常 大的数。 RSIZE_MAX 应该会发现这种不正确的用法。

引用 C11 (N1570), K.3.2 的“基本原理”部分:

3 非常大的对象尺寸通常表明对象的尺寸是经过计算的 不正确。例如,负数在以下情况下显示为非常大的正数 转换为无符号类型,如size_t。此外,某些实现不支持 与 size_t 类型可以表示的最大值一样大的对象。

4 出于这些原因,有时限制要检测的对象大小范围是有益的 编程错误。对于针对具有大地址空间的机器的实现, 建议将RSIZE_MAX定义为最大尺寸中的较小者 支持的对象或(SIZE_MAX >> 1),即使此限制小于 一些合法但非常大的对象。针对小型机器的实现 地址空间可能希望将RSIZE_MAX 定义为SIZE_MAX,这意味着不存在被视为违反运行时约束的对象大小。


值得注意的是,附件 K 的实现很少,并且有一个提议 (N1967) 弃用和/或从标准中删除它。

【讨论】:

  • @zwol 我会合并它(现在没有时间);但我相信 Wikipedia 提到 Open Watcom 也有一个符合要求的实现。
  • @zwol:MS 实现不符合标准,还是改变了?
  • @Deduplicator Annex K 绝对是 MS 的想法,但我不知道他们的实现是否完全符合要求。如果(例如)他们实施了早期草案,然后由于会破坏二进制兼容性而无法进行修订,我不会感到惊讶。
  • @zwol:有人要求放弃它,因为它是一个有严重缺陷且执行得更糟糕的坏主意:open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm
【解决方案2】:

这些类型定义具有语义含义。显然你可以在这里使用size_t(因为它是一样的),但是rsize_t更冗长:

size_t 类型通常覆盖整个地址空间。 ISO/IEC TR 24731-1-2007 引入了一种新类型 rsize_t,定义为 size_t 但明确用于保存单个对象的大小。 [1]

这与使用size_t 而不是unsigned int 时的情况类似。它基本相同,但名称不同,因此您很容易理解您正在使用的内容(size_t = "size of something",这意味着一个无符号整数)。

值得注意的是(正如 cmets 所建议的那样)rsize_t 在 C 规范中定义,但在 C++ 规范中没有定义。

【讨论】:

  • 最好将rsize_t 定义在C 规范中,而不是在C++ 规范中。
  • 不错的答案,但引用来自哪里?
  • size_t,我想它来自类型大小,但是 rsize_t? r 是什么意思?
  • @sop “受限”,我会说。 C11 K.3.2/4 说“出于这些原因,有时限制对象大小的范围以检测编程错误是有益的。对于针对具有大地址空间的机器的实现,建议将 RSIZE_MAX 定义为 ... "
猜你喜欢
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多