En C, se define en <stddef.h>y en C ++, se define en <cstddef>cuyo contenido es el mismo que el encabezado C (consulte la cita a continuación). Se define como un tipo entero sin signo del resultado del operador sizeof .
C Standard dice en §17.7 / 2,
size_t, que es el tipo entero sin signo del resultado del operador sizeof
Y el estándar C ++ dice (sobre el cstddefencabezado) en §18.1 / 3,
El contenido es el mismo que el encabezado de la biblioteca estándar C, con los siguientes cambios .
Entonces sí, ambos son iguales; La única diferencia es que C ++ define size_ten el stdespacio de nombres.
Tenga en cuenta también que la línea anterior también dice "con los siguientes cambios" a los que no se refiere size_t. Se refiere más bien a las nuevas adiciones (en su mayoría) realizadas por C ++ en el lenguaje (no presente en C) que también se definen en el mismo encabezado.
Wikipedia tiene muy buena información sobre el rango y el tamaño de almacenamiento de size_t:
Rango y tamaño de almacenamiento de size_t
El tipo real de size_t
depende de la plataforma ; un error común
es asumir que size_t es lo mismo que unsigned int, lo que puede conducir a errores de programación, [3] [4] al pasar de una arquitectura de 32 a 64 bits, por ejemplo.
Según el estándar ISO C 1999 (C99), size_t es un tipo entero sin signo de al menos 16 bits.
Y el resto lo puedes leer desde esta página en wikipedia.
Eso lleva a otra Q, si STL ya importa size_t a través de C (cstddef), ¿por qué tiene su propia otra versión nuevamente?
Alok Save
43
@Als: Estrictamente hablando, es un error decir size_tsin using namespace std;o using std::size_t;. Sin embargo, la mayoría de los compiladores lo permiten, y el Estándar específicamente les permite permitirlo (§D.5 / 3).
Potatoswatter
9
@Potatoswatter: ¿Seguramente no puede ser tanto un error como específicamente permitido en el estándar? Si está en el estándar, ¡no es un error!
Ben Hymers
8
@BenHymers El estándar especifica lo que declaran los encabezados estándar, y no se les permite declarar ningún otro nombre no reservado. El encabezado <cstddef>puede o no declararse ::size_t, por lo que no puede confiar en que esté allí o esté ausente, a menos que incluya específicamente <stddef.h>u otro encabezado de la biblioteca C que garantice su declaración.
Potatoswatter
44
@Potatoswatter: ¡Ah, ahora entiendo lo que quieres decir! Debo haberme confundido con demasiados "permisos" en una oración. Sin embargo, sigo pensando que tu primer comentario es demasiado fuerte; como acabas de decir, ::size_testá presente <stddef.h>, por ejemplo , en , por lo que no siempre necesitas calificarlo std::.
Ben Hymers
16
Desde C ++ 03 "17.4.3.1.4 Tipos":
Para cada tipo T de la biblioteca C estándar (nota 169), los tipos :: T y std :: T están reservados para la implementación y, cuando se define, :: T será idéntico a std :: T.
Y nota 169:
Estos tipos son clock_t, div_t, FILE, fpos_t, lconv, ldiv_t, mbstate_t, ptrdiff_t, sig_atomic_t, size_t, time_t, tm, va_list, wctrans_t, wctype_t y wint_t.
¿Entonces el código portátil no debería depender de las std::Tvariantes que se definen?
Mankarse
55
@Mankarse: No debe confiar en que se definan si solo incluye la versión C del encabezado correspondiente. Si #include <stddef.h>luego std::size_tpuede o no estar disponible. Si #include <cstddef>entonces std::size_testá disponible, pero size_tpodría no estarlo.
Dennis Zickefoose
44
@Mankarse: El opuesto. Las versiones C ++ de los encabezados deben definirlos std::y el párrafo dice que también puede definirlos en el espacio de nombres de nivel superior y, si lo hace, debe definirlos de manera idéntica std::y en el nivel superior. La mayoría de los compiladores solo incluyen el encabezado C e importan los nombres std::, por lo que los símbolos terminan definidos en ambos.
Jan Hudec
44
Personalmente, nunca me molesto con los encabezados <cxxxxx> o las std::variantes de identificadores que provienen de la orilla C. Me quedo con <xxxxx.h>los encabezados C estándar: nunca ha sido un problema. Por lo tanto, me gustaría usar <stddef.h>y size_tnunca dar un segundo pensamiento a std::size_t; de hecho, nunca se me ocurre que hay (o podría haber) a std::size_t.
Como señala Nawaz, en realidad es al revés. No puede incluir <cstddef>y esperar obtener ::size_t, pero si lo incluye <stddef.h>, obtendrá std::size_t.
MSalters
44
@MSalters, no te sigo. La inclusión <stddef.h>solo te atrapará ::size_t.
hifier
2
Eso es un error en su implementación, entonces.
MSalters
44
@MSalters, no entiendo del todo. ¿No debería ser al revés? <cstddef> proviene de C ++, por lo tanto, ¿debería definir las cosas en std :: *? Por otro lado, en un encabezado C, como stddef.h, solo esperaría el tipo C, es decir :: size_t.
Ela782
11
@MSalters, ya que C ++ 11 no es exacto. Si incluye <cstddef>, tiene garantizado obtener std::size_ty también puede obtener ::size_t(pero no está garantizado). Si incluye <stddef.h>está garantizado obtener ::size_ty también puede obtener std::size_t(pero no está garantizado). Era diferente en C ++ 03, pero eso no fue implementable y se solucionó como un defecto.
Respuestas:
C
size_t
y C ++std::size_t
son los mismos.En C, se define en
<stddef.h>
y en C ++, se define en<cstddef>
cuyo contenido es el mismo que el encabezado C (consulte la cita a continuación). Se define como un tipo entero sin signo del resultado del operador sizeof .C Standard dice en §17.7 / 2,
Y el estándar C ++ dice (sobre el
cstddef
encabezado) en §18.1 / 3,Entonces sí, ambos son iguales; La única diferencia es que C ++ define
size_t
en elstd
espacio de nombres.Tenga en cuenta también que la línea anterior también dice "con los siguientes cambios" a los que no se refiere
size_t
. Se refiere más bien a las nuevas adiciones (en su mayoría) realizadas por C ++ en el lenguaje (no presente en C) que también se definen en el mismo encabezado.Wikipedia tiene muy buena información sobre el rango y el tamaño de almacenamiento de size_t:
Y el resto lo puedes leer desde esta página en wikipedia.
fuente
size_t
sinusing namespace std;
ousing std::size_t;
. Sin embargo, la mayoría de los compiladores lo permiten, y el Estándar específicamente les permite permitirlo (§D.5 / 3).<cstddef>
puede o no declararse::size_t
, por lo que no puede confiar en que esté allí o esté ausente, a menos que incluya específicamente<stddef.h>
u otro encabezado de la biblioteca C que garantice su declaración.::size_t
está presente<stddef.h>
, por ejemplo , en , por lo que no siempre necesitas calificarlostd::
.Desde C ++ 03 "17.4.3.1.4 Tipos":
Y nota 169:
fuente
std::T
variantes que se definen?#include <stddef.h>
luegostd::size_t
puede o no estar disponible. Si#include <cstddef>
entoncesstd::size_t
está disponible, perosize_t
podría no estarlo.std::
y el párrafo dice que también puede definirlos en el espacio de nombres de nivel superior y, si lo hace, debe definirlos de manera idénticastd::
y en el nivel superior. La mayoría de los compiladores solo incluyen el encabezado C e importan los nombresstd::
, por lo que los símbolos terminan definidos en ambos.std::
variantes de identificadores que provienen de la orilla C. Me quedo con<xxxxx.h>
los encabezados C estándar: nunca ha sido un problema. Por lo tanto, me gustaría usar<stddef.h>
ysize_t
nunca dar un segundo pensamiento astd::size_t
; de hecho, nunca se me ocurre que hay (o podría haber) astd::size_t
.std :: size_t es de hecho stddef.h 's size_t .
cstddef da lo siguiente:
... trayendo efectivamente la definición anterior al espacio de nombres estándar.
fuente
<cstddef>
y esperar obtener::size_t
, pero si lo incluye<stddef.h>
, obtendrástd::size_t
.<stddef.h>
solo te atrapará::size_t
.<cstddef>
, tiene garantizado obtenerstd::size_t
y también puede obtener::size_t
(pero no está garantizado). Si incluye<stddef.h>
está garantizado obtener::size_t
y también puede obtenerstd::size_t
(pero no está garantizado). Era diferente en C ++ 03, pero eso no fue implementable y se solucionó como un defecto.