¿Por qué se define rsize_t?

5 minutos de lectura

avatar de usuario de zangw
zangw

encontre eso strncpy_s() se define bajo VS2013 como

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

typedef size_t rsize_t;

Creo que es un truco hecho por Estudio visual. Sin embargo, encontré esta función definida de la siguiente manera en este página

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

Por que es rsize_t definido aquí?

Y si size_t se usó aquí?

Cualquier caso especial para usar esto rsize_t?

  • ¿No es esto un estudio visual específico? typedef? No parece aparecer en mis archivos de encabezado, ni parece aparecer en mi borrador estándar.

    – Rey del cielo

    9 de noviembre de 2015 a las 8:18

  • Puede (o no) encontrar información útil en ¿Utiliza las funciones “seguras” del TR-24731? Al menos, hay algunos problemas destacados allí que debe tener en cuenta si le preocupa la portabilidad.

    –Jonathan Leffler

    9 de noviembre de 2015 a las 19:16

Angew ya no está orgulloso del avatar de usuario de SO
Angew ya no está orgulloso de SO

Lo ha encontrado en la biblioteca estándar de C++ de Microsoft, pero en realidad proviene de C. C 11, para ser precisos, lo que significa que técnicamente no es parte de C++.

Norma C 11, Anexo K introdujo todos los _s funciones y los correspondientes typedefs, incluyendo rsize_t. También hay una macro de “valor máximo” RSIZE_MAX que es lo suficientemente grande para aplicaciones típicas, pero más pequeño que el valor máximo real del tipo. Las funciones seguras no hacen nada e informan un error cuando un valor de tipo rsize_t excede RSIZE_MAX.

La idea es evitar fallas en el desbordamiento del búfer y errores similares causados ​​por tamaños no válidos, generalmente como resultado del uso de un valor negativo para el tamaño. En la representación de valor con signo en complemento a 2 (la más común), un número negativo corresponde a un muy gran número cuando se trata como sin firmar. RSIZE_MAX debería detectar tal uso incorrecto.

Citando la parte “fundamental” de C11 (N1570), K.3.2:

3 Los tamaños de objetos extremadamente grandes suelen ser una señal de que el tamaño de un objeto se calculó incorrectamente. Por ejemplo, los números negativos aparecen como números positivos muy grandes cuando se convierten a un tipo sin signo como size_t. Además, algunas implementaciones no admiten objetos tan grandes como el valor máximo que se puede representar por tipo size_t.

4 Por esas razones, a veces es beneficioso restringir el rango de tamaños de objetos para detectar errores de programación. Para implementaciones dirigidas a máquinas con grandes espacios de direcciones, se recomienda que RSIZE_MAX definirse como el menor del tamaño del objeto más grande soportado o (SIZE_MAX >> 1), incluso si este límite es más pequeño que el tamaño de algunos objetos legítimos, pero muy grandes. Las implementaciones dirigidas a máquinas con pequeños espacios de direcciones pueden desear definir RSIZE_MAX como SIZE_MAXlo que significa que no hay ningún tamaño de objeto que se considere una infracción de restricción de tiempo de ejecución.


Vale la pena señalar que el Anexo K tiene muy pocas implementaciones y hay una propuesta (N1967) para desaprobarlo y/o eliminarlo del estándar.

  • @zwol incorporaré eso (ahora no hay tiempo); pero creo que Wikipedia menciona que Open Watcom también tiene una implementación conforme.

    – Angew ya no está orgulloso de SO

    9 de noviembre de 2015 a las 15:17


  • @zwol: ¿Y la implementación de MS no es conforme, o eso cambió?

    – Deduplicador

    9 de noviembre de 2015 a las 18:04

  • @Deduplicator Anexo K definitivamente fue idea de MS, pero no sé si su implementación se ajusta completamente. No me sorprendería si (por ejemplo) implementaran un borrador inicial y luego no pudieran retomar las revisiones porque eso rompería la compatibilidad binaria.

    – zwol

    9 de noviembre de 2015 a las 18:07

  • @zwol: Hay una solicitud para abandonarlo como una mala idea gravemente defectuosa e incluso peor ejecutada: open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm

    – Deduplicador

    9 de noviembre de 2015 a las 20:18

Avatar de usuario de SingerOfTheFall
SingerOfTheFall

Estos typedefs tienen un significado semántico. Obviamente puedes usar size_t aquí (ya que es lo mismo), pero rsize_t es más detallado:

El tipo size_t generalmente cubre todo el espacio de direcciones. ISO/IEC TR 24731-1-2007 introduce un nuevo tipo rsize_t, definido como size_t pero utilizado explícitamente para contener el tamaño de un solo objeto. [1]

Es la situación similar a cuando se usa size_t en vez de unsigned int. Es básicamente lo mismo, pero con un nombre diferente, por lo que es fácil para usted entender con qué está trabajando (size_t = “tamaño de algo”, lo que implica un número entero sin signo).

Vale la pena señalar (como lo sugieren los comentarios) que rsize_t se define en la especificación C, pero no en la especificación C++.

  • Podría ser una buena idea incluir el hecho de que rsize_t se define en la especificación C, pero no en la especificación C++.

    – Un tipo programador

    9 de noviembre de 2015 a las 8:18

  • Buena respuesta, pero ¿de dónde está tomada la cita?

    –Tommy Andersen

    9 de noviembre de 2015 a las 8:19

  • size_t, supongo que viene del tamaño de letra, pero rsize_t? ¿Qué significa la r?

    – sop

    9 de noviembre de 2015 a las 8:21

  • @sop “Restringido”, diría yo. C11 K.3.2/4 dice: “Por esas razones, a veces es beneficioso restringir el rango de tamaños de objetos para detectar errores de programación. Para implementaciones dirigidas a máquinas con grandes espacios de direcciones, se recomienda que RSIZE_MAX definirse como…”

    – Angew ya no está orgulloso de SO

    9 de noviembre de 2015 a las 8:24

¿Ha sido útil esta solución?