Подтвердить что ты не робот

Почему определяется rsize_t?

Я обнаружил, что 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. Однако я обнаружил, что эта функция определена следующим образом на этой странице

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

Почему здесь определяется rsize_t?

Что, если size_t был использован здесь?

Какие-нибудь особые случаи, чтобы использовать это rsize_t?

4b9b3361

Ответ 1

Вы столкнулись с ним в стандартной библиотеке Microsoft С++, но на самом деле это происходит от C. C 11, если быть точным, что означает, что это не технически часть С++.

C 11 standard, Приложение K ввело все функции _s и соответствующие typedefs, включая rsize_t. Существует также макрос "максимальное значение" RSIZE_MAX, который достаточно велик для типичных приложений, но меньше реального максимального значения типа. Защищенные функции ничего не делают и сообщают об ошибке, когда значение типа rsize_t превышает RSIZE_MAX.

Идея состоит в том, чтобы избежать сбоев при переполнении буфера и подобных ошибок, вызванных недопустимыми размерами, обычно в результате использования отрицательного значения для размера. В представлении с 2-значным знаком знака (наиболее распространенным) отрицательное число соответствует очень большому числу, когда рассматривается как unsigned. RSIZE_MAX следует использовать такое неправильное использование.

Цитирование "обоснования" части C11 (N1570), K.3.2:

3 Чрезвычайно большие размеры объектов часто являются признаком того, что был рассчитан размер объектов неправильно. Например, отрицательные числа появляются как очень большие положительные числа, когда преобразуется в неподписанный тип, например size_t. Кроме того, некоторые реализации не поддерживают объекты, максимальные значения которых могут быть представлены типом size_t.

4 По этим причинам иногда бывает полезно ограничить диапазон размеров объектов для обнаружения ошибки программирования. Для реализаций, ориентированных на машины с большими адресными пространствами, рекомендуется, чтобы RSIZE_MAX определялся как меньший размер самого большого объект поддерживается или (SIZE_MAX >> 1), даже если этот предел меньше размера некоторые законные, но очень большие объекты. Реализации, ориентированные на машины с небольшими адресные пространства, возможно, пожелают определить RSIZE_MAX как SIZE_MAX, что означает, что нет размера объекта, который считается нарушением среды выполнения.


Стоит отметить, что приложение K имеет очень мало реализаций, и есть предложение (N1967), чтобы осудить и/или удалить его от стандарта.

Ответ 2

Эти typedefs имеют смысловое значение. Очевидно, вы можете использовать size_t здесь (так как это то же самое), но rsize_t более подробный:

Тип size_t обычно охватывает все адресное пространство. ISO/IEC TR 24731-1-2007 вводит новый тип rsize_t, определенный как size_t, но явно используемый для хранения размера одного объекта. [1]

Это аналогичная ситуация, когда при использовании size_t вместо unsigned int. Это в основном то же самое, но названо по-разному, поэтому вам легко понять, с чем вы работаете (size_t= "размер чего-то", что подразумевает целое число без знака).

Стоит отметить (как было предложено в комментариях), что rsize_t определяется в спецификации C, но не в спецификации С++.