c++ - que - ¿Por qué se define rsize_t?
size_t c++ que es (2)
Estas definiciones de tipo tienen un significado semántico. Obviamente, puedes usar size_t
aquí (ya que es el mismo), pero rsize_t
es más detallado:
El tipo size_t generalmente cubre todo el espacio de direcciones. ISO / CEI TR 24731-1-2007 introduce un nuevo tipo rsize_t, definido como tamaño_t pero que se usa explícitamente para mantener el tamaño de un solo objeto. [1]
Es la situación similar a la que se usa cuando se usa size_t
lugar de unsigned int
. Básicamente es el mismo, pero tiene un nombre diferente, por lo que es fácil para ti entender con qué estás 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
está definido en la especificación C, pero no en la especificación C ++.
Encontré que strncpy_s()
está definido en 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 Visual Studio . Sin embargo, encontré esta función definida de la siguiente manera en esta page
errno_t strncpy_s(char *restrict dest, rsize_t destsz,
const char *restrict src, rsize_t count);
¿Por qué se define aquí rsize_t
? ¿Qué pasa si size_t
fue utilizado aquí? ¿Algún caso especial para usar este rsize_t
?
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 ++.
Estándar C 11, el Anexo K introdujo todas las funciones _s
y las 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ña 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
supera RSIZE_MAX
.
La idea es evitar bloqueos en el exceso de búfer y errores similares causados por tamaños no válidos, que generalmente resultan de usar un valor negativo para el tamaño. En la representación del valor firmado del complemento de 2 (el más común), un número negativo corresponde a un número muy grande cuando se trata como sin signo. RSIZE_MAX
debería detectar ese uso incorrecto.
Citando la parte "racional" 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 con el tiposize_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
se defina como el tamaño más pequeño del objeto más grande admitido o(SIZE_MAX >> 1)
, incluso si este límite es más pequeño que el tamaño de algunos legítimos, pero muy grandes, objetos. Las implementaciones dirigidas a máquinas con espacios de direcciones pequeños pueden desear definirRSIZE_MAX
comoSIZE_MAX
, lo que significa que no hay un tamaño de objeto que se considere una violación de restricción de tiempo de ejecución.
Vale la pena señalar que el Anexo K tiene muy pocas implementaciones y existe una propuesta ( N1967 ) para desaprobarla y / o eliminarla de la norma.