ssize_t - size_t c++
¿Es size_t el tamaño de palabra? (6)
¿ size_t
es el tamaño de palabra de la máquina que compiló el código?
Al analizar g ++, mi compilador visualiza size_t
como un long unsigned int
. ¿El compilador elige internamente el tamaño de size_t
, o es size_t
realmente definido dentro de una macro stddef.h
en stddef.h
al tamaño de palabra antes de que se invoque al compilador?
¿O estoy fuera de la pista?
Aunque la definición no establece directamente qué tipo es exactamente size_t
, y ni siquiera requiere un tamaño mínimo , indirectamente da algunas buenas pistas. Un size_t
debe poder contener el tamaño en bytes de cualquier objeto, en otras palabras, debe poder contener el tamaño del objeto más grande posible.
El objeto más grande posible es una matriz (o estructura) con un tamaño igual a todo el espacio de direcciones disponible. No es posible hacer referencia a un objeto más grande de manera significativa, y aparte de la disponibilidad de espacio de intercambio, no hay ninguna razón por la que deba ser más pequeño .
Por lo tanto, según la redacción de la definición, size_t
debe tener al menos 32 bits en una arquitectura de 32 bits, y al menos 64 bits en un sistema de 64 bits. Por supuesto, es posible que una implementación elija un tamaño más size_t
, pero este no suele ser el caso.
En el estándar de C ++, [support.types] (18.2) / 6: "El tipo size_t
es un tipo entero sin signo definido por la implementación que es lo suficientemente grande como para contener el tamaño en bytes de cualquier objeto".
Esto puede o no ser lo mismo que un "tamaño de palabra", lo que sea que eso signifique.
No necesariamente. La especificación C ISO (§17.1 / 2) define size_t
como
size_t, que es el tipo entero sin signo del resultado del operador
sizeof
En otras palabras, size_t
tiene que ser lo suficientemente grande como para contener el tamaño de cualquier expresión que pueda producirse desde sizeof
. Este podría ser el tamaño de la máquina, pero podría ser dramáticamente más pequeño (si, por ejemplo, el compilador limitara el tamaño máximo de arrays u objetos) o dramáticamente más grande (si el compilador fuera a permitirle crear objetos tan grandes que una sola máquina La palabra no pudo almacenar el tamaño de ese objeto).
¡Espero que esto ayude!
No; size_t
no es necesariamente lo que quiere decir con ''tamaño de palabra'' de la máquina que ejecutará el código (en el caso de compilación cruzada) o que compiló el código (en el caso normal en el que el código se ejecutará en el mismo tipo de máquina que compiló el código). Es un tipo entero sin signo lo suficientemente grande como para contener el tamaño (en bytes) del objeto más grande que la implementación puede asignar.
Algunos antecedentes de sizeof
y size_t
No sé cuándo se introdujo size_t
exactamente, pero fue entre 1979 y 1989. La primera edición de K & R The C Programming Language de 1978 no menciona a size_t
. El Manual del programador de Unix de la 7ª edición no menciona en absoluto el size_t
, y data de 1979. El libro "El entorno de programación UNIX" de Kernighan y Pike de 1984 no menciona el size_t
en el índice (ni de malloc()
ni free()
, algo para mi sorpresa), pero eso es solo indicativo, no concluyente. El estándar C89 ciertamente tiene size_t
.
El C99 Rationale documenta cierta información sobre sizeof()
y size_t
:
6.5.3.4 El operador sizeof
Es fundamental para el uso correcto de funciones como
malloc
yfread
quesizeof(char)
sea exactamente uno. En la práctica, esto significa que un byte en términos de C es la unidad de almacenamiento más pequeña, incluso si esta unidad tiene 36 bits de ancho; y todos los objetos se componen de un número entero de estas unidades más pequeñas. También se aplica si la memoria es direccionable por bit. C89, al igual que K&R, definió el resultado del operadorsizeof
como una constante de un tipo entero sin signo. Las implementaciones comunes, y el uso común, a menudo han asumido que el tipo resultante esint
. El código antiguo que depende de este comportamiento nunca ha sido transferible a las implementaciones que definen el resultado como un tipo distinto deint
. El Comité C89 consideró que no era apropiado cambiar el idioma para proteger el código incorrecto.El tipo de
sizeof
, cualquiera que sea, se publica (en el encabezado de la biblioteca<stddef.h>
) comosize_t
, ya que es útil para que el programador pueda referirse a este tipo. Este requisito restringe implícitamente quesize_t
sea un sinónimo para un tipo de entero sin signo existente. Tenga en cuenta también que, si biensize_t
es un tipo sin signo,sizeof
no implica ninguna operación aritmética o conversiones que den lugar a un comportamiento de módulo si el tamaño es demasiado grande para representar comosize_t
, anulando así la noción de que el objeto más grande declarable podría ser demasiado grande para abarcar incluso con ununsigned long
en C89 ouintmax_t
en C99. Esto también restringe el número máximo de elementos que se pueden declarar en una matriz, ya que para cualquier matriz deN
elementos,
N == sizeof(a)/sizeof(a[0])
Por lo tanto
size_t
también es un tipo conveniente para tamaños de matriz, y así se usa en varias funciones de biblioteca. [...]7.17 Definiciones comunes
<stddef.h>
es un encabezado inventado para proporcionar definiciones de varios tipos y macros que se usan ampliamente en conjunto con la biblioteca:ptrdiff_t
,size_t
,wchar_t
yNULL
. Incluir cualquier encabezado que haga referencia a una de estas macros también lo definirá, una excepción a la regla de la biblioteca habitual de que cada macro o función pertenece exactamente a un encabezado.
Tenga en cuenta que esto menciona específicamente que el <stddef.h>
fue inventado por el comité C89. No he encontrado palabras que digan que size_t
también fue inventado por el comité C89, pero si no fue así, fue una codificación de un desarrollo bastante reciente en C.
En un comentario a la answer bmargulies , vonbrand dice que ''it [ size_t
] es ciertamente un ANSI-C-ismo''. Puedo creer fácilmente que fue una innovación con el ANSI (ISO) original C, aunque es ligeramente extraño que el razonamiento no lo indique.
Tales definiciones son todas de implementación definida. Usaría sizeof (char *), o quizás sizeof (void *), si necesitara un mejor tamaño de adivinar. Lo mejor que ofrece es el uso aparente del software de tamaño de palabra ... lo que realmente tiene el hardware puede ser diferente (por ejemplo, un sistema de 32 bits puede admitir enteros de 64 bits por software).
Además, si es nuevo en los lenguajes C, consulte stdint.h para todo tipo de material en tamaños enteros.
size_t era, originalmente, solo un typedef en sys / types.h (tradicionalmente en Unix / Linux). Se supuso que era "lo suficientemente grande" para, por ejemplo, el tamaño máximo de un archivo o la asignación máxima con malloc. Sin embargo, con el tiempo, los comités estándar lo tomaron, y así se copiaron en muchos archivos de encabezado diferentes, protegidos cada vez con su propia protección #ifdef de la definición múltiple. Por otro lado, la aparición de sistemas de 64 bits con tamaños de archivo de potencial muy grande nubló su papel. Así que es un poco un palimpset.
Los estándares de lenguaje ahora lo dicen como vivir en stddef.h. No tiene una relación necesaria con el tamaño de palabra del hardware, y no tiene magia de compilación. Vea otras respuestas con respecto a lo que esos estándares dicen sobre lo grande que es.