Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is rsize_t defined?

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?

like image 322
zangw Avatar asked Nov 09 '15 08:11

zangw


People also ask

Where is Rsize_t defined?

It is worth noting (as suggested by the comments) that rsize_t is defined in the C specification, but not in the C++ specification. It might be a good idea to include the fact that rsize_t is defined in the C specification, but not in the C++ specification.

What is Rsize_t?

The 'rsize_t' is an unsigned integer type and is very similar to the type size_t. The 'size_t' type is a result of the 'sizeof' operator. Variables of the 'size_t' type are guaranteed to have enough capacity to store the size of any object or array of objects. The largest value such a variable can store is SIZE_MAX.

What is rsize_ MAX?

RSIZE_MAX. (C11) largest acceptable size for bounds-checked functions, expands to either constant or variable which may change at runtime (e.g. as the currently allocated memory size changes)


2 Answers

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.

like image 152
Angew is no longer proud of SO Avatar answered Oct 05 '22 07:10

Angew is no longer proud of SO


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.

like image 38
SingerOfTheFall Avatar answered Oct 05 '22 05:10

SingerOfTheFall