Why is rsize_t defined?

感情迁移 提交于 2019-12-13 11:52:00

问题


I found that strncpy_s() is defined under VS2013 as

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 is:

typedef size_t rsize_t;

I think it's a trick done by Visual Studio. However, I found this function defined as follows on this page

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

Why is rsize_t defined here?

What if size_t was used here?

Any special cases to use this rsize_t?


回答1:


You've encountered it in Microsoft's C++ standard library, but it actually comes from C. C 11, to be precise, which means it's not technically a part of C++.

C 11 standard, Annex K introduced all the _s functions and the corresponding typedefs, including rsize_t. There is also a "maximum value" macro RSIZE_MAX which is large enough for typical applications, but smaller than the real maximum value of the type. The secure functions do nothing and report an error when a value of type rsize_t exceeds RSIZE_MAX.

The idea is to avoid crashes on buffer overruns and similar errors caused by invalid sizes, usually resulting from using a negative value for size. In 2's complement signed value representation (the most common one), a negative number corresponds to a very large number when treated as unsigned. RSIZE_MAX should catch such incorrect use.

Quoting the "rationale" part of C11 (N1570), K.3.2:

3 Extremely large object sizes are frequently a sign that an object’s size was calculated incorrectly. For example, negative numbers appear as very large positive numbers when converted to an unsigned type like size_t. Also, some implementations do not support objects as large as the maximum value that can be represented by type size_t.

4 For those reasons, it is sometimes beneficial to restrict the range of object sizes to detect programming errors. For implementations targeting machines with large address spaces, it is recommended that RSIZE_MAX be defined as the smaller of the size of the largest object supported or (SIZE_MAX >> 1), even if this limit is smaller than the size of some legitimate, but very large, objects. Implementations targeting machines with small address spaces may wish to define RSIZE_MAX as SIZE_MAX, which means that there is no object size that is considered a runtime-constraint violation.


It is worth noting that Annex K has very few implementations and there is a proposal (N1967) to deprecate and/or remove it from the standard.




回答2:


These typedefs have semantic meaning. Obviously you can use size_t here (since it's the same), but rsize_t is more verbose:

The type size_t generally covers the entire address space. ISO/IEC TR 24731-1-2007 introduces a new type rsize_t, defined to be size_t but explicitly used to hold the size of a single object. [1]

It's the similar situation as when using size_t instead of unsigned int. It's basically the same, but named differently so it's easy for you to understand what you're working with (size_t = "size of something", which implies an unsigned whole number).

It is worth noting (as suggested by the comments) that rsize_t is defined in the C specification, but not in the C++ specification.



来源:https://stackoverflow.com/questions/33604857/why-is-rsize-t-defined

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!