¿Tiene "std:: size_t" sentido en C++?
size-t (8)
En algún código que heredé, veo el uso frecuente de size_t
con el calificador de espacio de nombres std
. Por ejemplo:
std::size_t n = sizeof( long );
Se compila y funciona bien, por supuesto. Pero me parece una mala práctica (¿quizás transferida desde C?).
¿No es cierto que size_t
está integrado en C ++ y, por lo tanto, en el espacio de nombres global? ¿Se necesita incluir un archivo de cabecera para usar size_t
en C ++?
Otra forma de hacer esta pregunta es: ¿se esperaría que el siguiente programa ( sin incluir) compilara en todos los compiladores de C ++?
size_t foo()
{
return sizeof( long );
}
En ocasiones, otras bibliotecas definirán su propio tamaño_t. Por ejemplo, impulso. std :: size_t especifica que definitivamente quieres el estándar de c ++.
size_t es un tipo estándar de C ++ y está definido dentro del espacio de nombres std.
La sección 17.4.1.2 del estándar C ++, párrafo 4, establece que:
"Sin embargo, en la Biblioteca estándar de C ++, las declaraciones y definiciones (excepto los nombres que se definen como macros en C) se encuentran dentro del ámbito de espacio de nombres (3.3.5) del espacio de nombres std."
Esto incluye los elementos que se encuentran en los encabezados del patrón cname , incluido cstddef , que define size_t.
Entonces std :: size_t es de hecho correcto.
Puede obtener size_t
en el espacio de nombres global incluyendo, por ejemplo, <stddef.h>
lugar de <cstddef>
. No puedo ver ningún beneficio obvio, y la función está en desuso.
size_t no está integrado en C ++. Y no está definido por defecto. Este no compila con GCC:
int main(int argc, char** argv) {
size_t size;
}
Dicho esto, size_t es parte de POSIX y si solo usas elementos básicos como <cstdlib>
, es probable que <cstdlib>
definiéndolo.
Se podría argumentar que std :: size_t es el equivalente de C ++ de size_t. Como señaló Brian, std :: se usa como espacio de nombres para evitar establecer variables globales que no se ajustan a todos. Es como std :: string, que también podría haberse definido en el espacio de nombres raíz.
Parece que hay confusión entre la multitud con respecto a esto
::size_t
se define en el encabezado de compatibilidad con versiones anteriores stddef.h
. Ha sido parte de ANSI/ISO C
y ISO C++
desde el principio. Cada implementación de C ++ debe enviarse con stddef.h
(compatibilidad) y cstddef
donde solo este último define std::size_t
y no necesariamente ::size_t
. Ver el Anexo D del Estándar C ++.
Los encabezados del compilador GNU contienen algo así como
typedef long int __PTRDIFF_TYPE__; typedef unsigned long int __SIZE_TYPE__;
Entonces stddef.h constata algo así como
typedef __PTRDIFF_TYPE__ ptrdiff_t; typedef __SIZE_TYPE__ size_t;
Y finalmente el archivo cstddef contiene algo así como
#include <stddef.h> namespace std { using ::ptrdiff_t; using ::size_t; }
Creo que eso debería dejarlo en claro. Siempre que incluya <cstddef> puede usar size_t o std :: size_t porque size_t fue typedefed fuera del espacio de nombres std y luego se incluyó. Efectivamente tienes
typedef long int ptrdiff_t; typedef unsigned long int size_t; namespace std { using ::ptrdiff_t; using ::size_t; }
Creo que las aclaraciones son lo suficientemente claras. El std::size_t
tiene sentido en C ++ y ::size_t
tiene (al menos) buen sentido en C.
Sin embargo, queda una pregunta. A saber, si es seguro asumir que ::size_t
y std::size_t
son compatibles?
Desde una perspectiva puramente segura, no son necesariamente idénticos a menos que se defina en algún lugar que deben ser idénticos.
Creo que muchos están usando algo a la:
----
// a.hpp
#include <string>
void Foo( const std::string & name, size_t value );
-----
// a.cpp
#include "a.hpp"
using namespace std;
void Foo( const string & name, size_t value )
{
...
}
Entonces, en el encabezado definitivamente usas el ::size_t
mientras que en el archivo fuente std::size_t
. Entonces deben ser compatibles, ¿verdad? De lo contrario, obtendrá un error de compilación.
/ Michael S.
std::size_t n = sizeof( long );
En realidad, no ha preguntado qué parece ser específicamente una mala práctica en lo anterior. Uso de size_t, calificación con el espacio de nombre estándar, ...
Como dice el Estándar C ++ (18.1), size_t es un tipo definido en el encabezado estándar. Sugeriría dejar cualquier pensamiento e impresión sobre la posible herencia del lenguaje C. C ++ es un lenguaje separado y diferente y es mejor considerarlo como tal. Tiene su propia biblioteca estándar y todos los elementos de la Biblioteca estándar de C ++ están definidos dentro del espacio de nombres estándar. Sin embargo, es posible usar elementos de C Standard Library en el programa C ++.
Consideraría incluirlo como un sucio truco. El Estándar C ++ establece que el contenido de los encabezados es el mismo o está basado en los encabezados correspondientes de la Biblioteca estándar C, pero en el número de casos, se han aplicado cambios. En otras palabras, no es una copia y pegado directo de los encabezados C en los encabezados C ++.
size_t no es un tipo incorporado en C ++. Es un tipo definido para especificar qué tipo de tipo integral se utiliza como un tipo de retorno de sizeof () operador, porque un tipo de retorno real de sizeof () es la implementación definida, por lo que el estándar C ++ se unifica definiendo size_t.
se espera que el siguiente programa (sin incluir) compile en todos los compiladores C ++?
size_t foo() { return sizeof( long ); }
El estándar de C ++ dice (1.4):
Los nombres definidos en la biblioteca tienen un alcance de espacio de nombres (7.3). La unidad de traducción AC ++ (2.1) obtiene acceso a estos nombres incluyendo el encabezado de biblioteca estándar apropiado (16.2).
El tamaño_t es un nombre definido dentro del espacio de nombres estándar, por lo que cada programa que use este nombre debe incluir el encabezado correspondiente, en este caso.
A continuación, el capítulo 3.7.3 dice:
Sin embargo, refiriéndose a std, std :: bad_alloc, y std :: size_t está mal formado a menos que el nombre haya sido declarado incluyendo el encabezado apropiado.
Dado que, el programa que usa size_t pero que no incluye el encabezado está mal formado.