¿Dónde encuentro la definición de size_t?

123

Veo variables definidas con este tipo pero no sé de dónde viene, ni cuál es su propósito. ¿Por qué no usar int o unsigned int? (¿Qué pasa con otros tipos "similares"? Void_t, etc.).

Eliseo Ocampos
fuente
Pregunta exacta: stackoverflow.com/questions/502856/…
kjfletch
@kjfletch: hhhmmm, es extraño que la búsqueda del término 'size_t' (como hice anteriormente) no devolviera esa pregunta.
Eliseo Ocampos
1
@Eliseo - La función de búsqueda de Stackoverflow es horrible. En su lugar, utilice Google con un parámetro 'site: stackoverflow.com'.
Michael Burr
8
El OP preguntó específicamente ¿Dónde encuentro la definición de size_t? Aterricé aquí buscando lo mismo. El dup citado no discute dónde encontrar la declaración.
jww
9
Obviamente, esta pregunta no es la misma pregunta que la vinculada. "¿Dónde encuentro algo?" No es lo mismo que "¿Cuál es la diferencia entre" (incluso si la respuesta a uno proporciona la respuesta al otro). Mi búsqueda en Google de 'c ++ where is size_t definition' me llevó directamente aquí, y me habría perdido la otra pregunta, porque es diferente .
Dan Nissenbaum

Respuestas:

122

De Wikipedia

Los archivos de encabezado stdlib.hy stddef.hdefinen un tipo de datos llamado size_t1 que se usa para representar el tamaño de un objeto. Las funciones de biblioteca que toman tamaños esperan que sean de tipo size_t, y el operador sizeof se evalúa como size_t.

El tipo real de size_tdepende de la plataforma; un error común es asumir que size_tes lo mismo que unsigned int, lo que puede conducir a errores de programación, 2 particularmente a medida que las arquitecturas de 64 bits se vuelven más frecuentes.

Desde C99 7.17.1 / 2

Los siguientes tipos y macros se definen en el encabezado estándar stddef.h

<snip>

size_t

que es el tipo entero sin signo del resultado del operador sizeof

Martin Liversage
fuente
2
Por ejemplo, en Win64, los tipos inty unsigned intson de 32 bits, mientras que size_t es de 64 bits.
Michael Burr
7
Consulte las secciones 7.17 y 7.18.3 del estándar ISO C (99) (del cual incluye el estándar C ++)
Martin York
3
@LokiAstari, ¿por qué no edita la respuesta ya que sabe dónde está escrito en el estándar?
Hi-Angel
Entonces, ¿dónde está la respuesta de C ++?
Lothar
@Lothar Creo que la única diferencia es que size_t puede ser una palabra clave y, por lo demás, tiene el mismo significado.
Paul Stelian
30

De acuerdo con la descripción de size_t en en.cppreference.com size_t se define en los siguientes encabezados:

std::size_t

...    

Defined in header <cstddef>         
Defined in header <cstdio>      
Defined in header <cstring>         
Defined in header <ctime>       
Defined in header <cwchar>
StefanB
fuente
2
Esto es exactamente lo que necesitaba, esta respuesta debería ser votada a favor.
neodelphi
27

size_t es el tipo entero sin signo del resultado del operador sizeof (ISO C99 Sección 7.17.)

El sizeofoperador da el tamaño (en bytes) de su operando, que puede ser una expresión o el nombre entre paréntesis de un tipo. El tamaño se determina a partir del tipo de operando. El resultado es un número entero. El valor del resultado se define por la implementación y su tipo (un tipo entero sin signo) es size_t(ISO C99 Sección 6.5.3.4.)

fpmurphy
fuente
La mejor respuesta ya que cita el estándar.
Martin York
1
@Martin: es cierto, pero creo que la parte de la pregunta 'por qué no se usa el int sin firmar' es tan interesante (o más) como la parte 'qué es size_t', y no encontrará eso en el estándar .
Michael Burr
Sí, excepto que no hay 'Sección 17.17 ': p. Es raro, nadie dijo una palabra sobre Void_t
Eliseo Ocampos
Acepto esta respuesta ya que responde directamente a la pregunta, pero sería genial si se complementara con la respuesta de Michael.
Eliseo Ocampos
58
Lástima que su respuesta no me diga qué archivo de encabezado incluir.
Matt
6

En términos prácticos, size_trepresenta la cantidad de bytes que puede abordar. En la mayoría de las arquitecturas modernas durante los últimos 10-15 años, ha sido de 32 bits, que también ha sido del tamaño de un int sin firmar. Sin embargo, nos estamos moviendo a un direccionamiento de 64 bits, mientras que uintlo más probable es que se mantenga en 32 bits (su tamaño no está garantizado en el estándar c ++). Para hacer que su código que depende del tamaño de la memoria sea portátil entre arquitecturas, debe usar un size_t. Por ejemplo, cosas como los tamaños de matriz siempre deben usar size_t's. Si observa los contenedores estándar, ::size()siempre devuelve un size_t.

También tenga en cuenta que Visual Studio tiene una opción de compilación que puede verificar este tipo de errores denominada "Detectar problemas de portabilidad de 64 bits".

Precio de Matt
fuente
2

De esta manera siempre sabrá cuál es el tamaño, porque un tipo específico está dedicado a los tamaños. La propia pregunta muestra que puede ser un problema: ¿es una into una unsigned int? Además, ¿cuál es la magnitud ( short, int, long, etc.)?

Debido a que hay un tipo específico asignado, no tiene que preocuparse por la longitud o el signo.

La definición real se puede encontrar en la biblioteca de referencia de C ++ , que dice:

Tipo: size_t(tipo integral sin firmar)

Encabezamiento: <cstring>

size_tcorresponde al tipo de datos integral devuelto por el operador de lenguaje sizeofy se define en el <cstring>archivo de encabezado (entre otros) como un tipo integral sin firmar.

En <cstring>, se utiliza como el tipo del parámetro numen las funciones memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpyy strxfrm, que en todos los casos que se utiliza para especificar el número máximo de bytes o caracteres la función tiene que afectar.

También se utiliza como el tipo de cambio de strcspn, strlen, strspny strxfrmpara tamaños de retorno y longitudes.

lavinio
fuente
2

size_t debe definirse en los encabezados de su biblioteca estándar. En mi experiencia, generalmente es simplemente un typedef para unsigned int. Sin embargo, el punto es que no tiene por qué ser así. Los tipos como size_t permiten al proveedor de bibliotecas estándar la libertad de cambiar sus tipos de datos subyacentes si es apropiado para la plataforma. Si asume que size_t siempre es unsigned int (mediante conversión, etc.), podría tener problemas en el futuro si su proveedor cambia size_t para que sea, por ejemplo, un tipo de 64 bits. Es peligroso asumir algo sobre esta o cualquier otro tipo de biblioteca por este motivo.

Ryan
fuente
1

No estoy familiarizado void_texcepto como resultado de una búsqueda en Google (se usa en una vmallocbiblioteca por Kiem-Phong Vo en AT&T Research ; estoy seguro de que también se usa en otras bibliotecas).

Las diversas definiciones de tipo xxx_t se utilizan para abstraer un tipo de una implementación definida particular, ya que los tipos concretos utilizados para ciertas cosas pueden diferir de una plataforma a otra. Por ejemplo:

  • size_t abstrae el tipo usado para contener el tamaño de los objetos porque en algunos sistemas este será un valor de 32 bits, en otros puede ser de 16 o 64 bits.
  • Void_tabstrae el tipo de puntero devuelto por las vmallocrutinas de la biblioteca porque fue escrito para funcionar en sistemas anteriores a ANSI / ISO C donde elvoid palabra clave podría no existir. Al menos eso es lo que supongo.
  • wchar_t abstrae el tipo utilizado para caracteres anchos ya que en algunos sistemas será de 16 bits, en otros será de 32 bits.

Entonces, si escribe su código de manejo de caracteres amplios para usar el wchar_ttipo en lugar de, digamos unsigned short, ese código probablemente será más portátil para varias plataformas.

Michael Burr
fuente
Esto es lo que estaba buscando, en parte. Como dije en un comentario en la respuesta de fpmurphy, sería genial que se pueda complementar con esta respuesta (si no te importa, tal vez puedas editarlo) :)
Eliseo Ocampos
1

En programas minimalistas donde una size_tdefinición no se cargó "por casualidad" en algunos include pero todavía la necesito en algún contexto (por ejemplo, para acceder std::vector<double>), entonces uso ese contexto para extraer el tipo correcto. Por ejemplo typedef std::vector<double>::size_type size_t.

(Rodee con namespace {...}si es necesario para limitar el alcance).

alfC
fuente
1

En cuanto a "¿Por qué no usar int o unsigned int?", Simplemente porque semánticamente es más significativo no hacerlo. Existe la razón práctica por la que puede ser, digamos, typedefd como an inty luego actualizarse a un longposterior, sin que nadie tenga que cambiar su código, por supuesto, pero más fundamentalmente que se supone que un tipo es significativo. Para simplificar enormemente, una variable de tipo size_tes adecuada y se usa para contener los tamaños de las cosas, al igual que lo time_tes para contener valores de tiempo. La forma en que estos se implementan realmente debería ser una tarea de implementación bastante adecuada. En comparación con simplemente llamar a todo int, el uso de nombres de tipo significativos como este ayuda a aclarar el significado y la intención de su programa, al igual que lo hace cualquier conjunto rico de tipos.

Crowman
fuente