¿Por qué snprintf() toma un límite de tamaño de tipo size_t, pero devuelve un número entero de caracteres impresos?
La venerable función snprintf()
…
int snprintf( char *restrict buffer, size_t bufsz, const char *restrict format, ... );
- devuelve el número de caracteres que imprime, o más bien, el número que habría imprimido si no fuera por el límite del tamaño del buffer.
- toma el tamaño del buffer en caracteres/bytes.
¿Cómo tiene sentido que el tamaño del buffer sea de tipo size_t
, pero que el tipo de retorno sea solo un int
?
Si se supone que snprintf()
puede imprimir más de INT_MAX
caracteres en el buffer, ¿no debería devolver un ssize_t
o un size_t
con (size_t) - 1
indicando un error, ¿verdad?
Y si no se supone que pueda imprimir más de INT_MAX
caracteres, ¿por qué bufsz
es un size_t
en lugar de, por ejemplo, un unsigned
o un int
? ¿O al menos está oficialmente limitado a contener valores no mayores que INT_MAX
?
davy.ai
Puede parecer extraño que el tamaño del búfer para
snprintf()
se declare comosize_t
, pero la función devuelve unint
. Sin embargo, esto se debe a que el propósito principal desnprintf()
es escribir datos formateados en un búfer, no simplemente devolver el número de caracteres que se habrían escrito si el tamaño del búfer fuera lo suficientemente grande.El valor de retorno de
snprintf()
es más bien una característica secundaria que sirve como indicador de error si la salida se truncó debido al límite de tamaño del búfer. En otras palabras, si el valor de retorno es menor que el tamaño del búfer, entonces la salida se escribió correctamente en el búfer sin ninguna truncación. Si el valor de retorno es mayor o igual que el tamaño del búfer, entonces la salida se truncó y el valor de retorno indica cuántos caracteres se habrían escrito si el tamaño del búfer fuera mayor.En cuanto al tamaño máximo del búfer admitido por
snprintf()
, el estándar C no impone ningún límite específico enbufsz
, pero la implementación del sistema puede tener sus propias limitaciones. En la práctica, a menudo se utilizasize_t
para representar tamaños de búfer porque proporciona un rango lo suficientemente grande como para adaptarse a la mayoría de las aplicaciones prácticas. El hecho de quesize_t
sea un entero sin signo significa que los tamaños de búfer no pueden ser negativos, lo cual es una propiedad deseable.