st_size
es defined como off_t
.¿Por qué se firma el campo st_size en struct stat?
off_t
es defined como entero con signo tipo.
¿Por qué se define st_size
como un tipo firmado? ¿Puede ser negativo? ¿Qué significa si es negativo?
st_size
es defined como off_t
.¿Por qué se firma el campo st_size en struct stat?
off_t
es defined como entero con signo tipo.
¿Por qué se define st_size
como un tipo firmado? ¿Puede ser negativo? ¿Qué significa si es negativo?
La mejor razón que se me ocurre es evitar introducir una versión sin firmar de off_t
como un tipo extra; POSIX ya tiene una abundancia ridícula de tipos enteros con usos similares.
Aparte de eso, ser capaz de almacenar -1 en st_size
cuando el tamaño no es un concepto que tenga sentido es probablemente útil; No estoy seguro de si alguna implementación hace esto, y no puedo encontrar dónde POSIX pone ningún requisito sobre los contenidos de st_size
excepto los archivos regulares y los enlaces simbólicos ...
off_t
define desplazamientos en un archivo, que podría ser igual al tamaño del archivo, pero también puede ser negativo, por ejemplo, si se busca al revés.
De esta relación entre desplazamiento y tamaño, el tamaño de un archivo tiene el mismo tipo que un desplazamiento de archivo. De todos modos, el tamaño de un archivo no debe ser negativo.
off_t
se utiliza para manejar desplazamientos de archivos en muchas funciones. Algunas funciones usan el valor especial -1 (por ejemplo, lseek
hace eso para indicar que se ha producido un error). Muchos otros tipos de datos se firman en UNIX para acomodar -1 valores (por ejemplo, time_t
).
Tenga en cuenta que el argumento de 'lseek' es una posición de archivo * relative * (desplazamiento), que es la razón principal por la que se debe firmar 'off_t'. Y el hecho de que solo pueda buscar posiciones positivas absolutas de archivos impone una restricción de que los archivos no pueden ser mayores que el valor máximo del tipo (firmado) 'off_t', por lo que no tiene sentido tener' filesize_t' que no esté firmado para mantener un tamaño mayor valores. –
Creo que alguna función fseek en POSIX necesita aceptar negativo como compensación.
Según las reglas de promoción de C, las expresiones que combinan diferentes tamaños de tipos firmados se comportarán de la misma manera aritméticamente correcta independientemente de los tamaños involucrados, siempre que ninguno de los cálculos intermedios se desborde. Sin embargo, agregar tipos sin firmar hará que el comportamiento del código sea mucho más dependiente de los tamaños enteros.
Dado:
int test_size(off_t x, long y, long long z)
{
return x-y > z;
}
Si off_t
estaban sin firmar, a continuación, dependiendo de su tamaño podría causar y
para obtener ascendido a unsigned long
, con el cálculo realizado sobre ese tipo, que luego ser promovido a signed long long
y comparado con z
usando una comparación firmada, o podría hacer que z
se promoviera a unsigned long long
, en cuyo caso la comparación general se haría de forma no firmada. También sería posible (aunque no necesariamente) que off_t
sea lo suficientemente pequeño (y/o long
lo suficientemente grande) para que y
se resta utilizando aritmética firmada.
Las cantidades que pueden ser lo suficientemente grandes como int
, aunque nunca sean negativas, generalmente deben estar representadas por tipos sin firmar solo si hay motivos para creer que no encajarán en un determinado signo tipo, pero sin duda encajaría en su contraparte sin signo. Tales situaciones no son terriblemente comunes, pero existían con size_t en sistemas de 16 bits (era arquitectónicamente imposible que un solo objeto superara los 64 K, pero los objetos de más de 32 K eran un lugar común).Tal escenario parecería menos convincente en una interfaz de sistema de archivos (si la firma de 32 bits no es suficiente, la suscripción de 32 bits probablemente tampoco sea suficiente durante mucho tiempo).
Interesante discurso sobre matemáticas de tipo mixto. Usar 'x-y * 1LL> z' en este hipotético puede ayudar un poco, y aún así tener fallas en las esquinas. Hmmm. – chux
¿Dónde coloca POSIX un requisito para 'st_size' para archivos regulares? – user1290696
POSIX requiere 'st_size' para reflejar el tamaño real del archivo para archivos normales, y requiere que refleje la longitud simbólica del enlace para enlaces simbólicos. El requisito para los enlaces simbólicos está documentado con 'stat'; el requisito de archivos regulares parece omitirse allí, pero la documentación para 'sys/stat.h' dice que para los archivos normales,' st_size' es el tamaño del archivo en bytes. –