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
?
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, includingrsize_t
. There is also a "maximum value" macroRSIZE_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 typersize_t
exceedsRSIZE_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:
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.
These typedefs have semantic meaning. Obviously you can use
size_t
here (since it's the same), butrsize_t
is more verbose:It's the similar situation as when using
size_t
instead ofunsigned 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.