¿Cuál es la diferencia entre stdint.h
y cstdint
?
Ambos están disponibles en MSVC (Visual Studio 2010) y gcc-4.5.1. También ambos definen los tipos intX_t
/ uintX_t
(donde X
es el tamaño en bytes del tipo).
- Si el fundamento en ambos encabezados es el mismo (tipos portátiles), ¿qué decisiones debo tomar para decidir sobre uno u otro?
El stdint.h
define cada tipo sin ningún espacio de nombres, los cstdint
tipos se encuentra en el std
espacio de nombres.
- ¿Hay alguna razón para incluir o no incluir los tipos definidos en el
std
espacio de nombres? ¿Qué es diferente entre los dos encabezados?
cstdint
no tiene extensión de archivo y usa el c
prefijo, stdint.h
usa la .h
extensión.
- ¿Cuáles son las convenciones de nomenclatura para estos encabezados? el
c
prefijo indica que se trata de una biblioteca C? hay una razón para la falta de extensión de archivo encstdint
?
<cstdint>
. Aquí está el error que recibo:./misc.h:7:10: fatal error: 'cstdint' file not found
.Respuestas:
La intención original en C ++ 98 era que se usara
<cstdint>
en C ++, para evitar contaminar el espacio de nombres global (bueno, no<cstdint>
en particular, eso solo se agrega en C ++ 11, pero los<c*>
encabezados en general).Sin embargo, las implementaciones persistieron en poner los símbolos en el espacio de nombres global de todos modos, y C ++ 11 ratificó esta práctica [*]. Entonces, básicamente tienes tres opciones:
<cstdint>
y califique completamente cada tipo de entero que use o bien, llévelo al alcance conusing std::int32_t;
etc. (molesto porque es detallado, pero es la forma correcta de hacerlo como para cualquier otro símbolo en la biblioteca estándar de C ++)<stdint.h>
(levemente malo porque obsoleto)<cstdint>
y asuma que su implementación colocará los símbolos en el espacio de nombres global (muy mal porque no está garantizado).En la práctica, sospecho que una gran cantidad de código molesta usa la última opción, simplemente porque es fácil de hacer por accidente en una implementación donde se
<cstdint>
colocan los símbolos en el espacio de nombres global. Deberías intentar usar el primero. La segunda tiene una virtud, que está garantizado poner cosas en el espacio de nombres global en lugar de solo hacerlo tal vez. No creo que eso sea particularmente útil, pero podría ahorrar algo de escritura si esa es su prioridad.Hay una cuarta opción,
#include <cstdint>
seguida de lausing namespace std;
que a veces es útil, pero hay lugares en los que no debes poner elusing namespace std;
. Diferentes personas tendrán diferentes ideas sobre dónde están esos lugares, pero "en el nivel superior en un archivo de encabezado" es peor que "en el nivel superior en un archivo cpp", que es peor que "en un alcance limitado". Algunas personas nunca escribenusing namespace std;
en absoluto.[*] Eso significa que los encabezados estándar de C ++ pueden poner cosas en el espacio de nombres global, pero no es obligatorio. Por lo tanto, debe evitar chocar con esos símbolos, pero en realidad no puede usarlos porque es posible que no estén allí. Básicamente, el espacio de nombres global en C ++ es un campo minado, trate de evitarlo. Se podría argumentar que el comité ha ratificado una práctica mediante implementaciones que es casi tan dañina como quedarse
using namespace std;
en el nivel superior en un archivo de encabezado; la diferencia es que las implementaciones solo lo hacen para símbolos en la biblioteca estándar de C, mientrasusing namespace std;
que lo hace para C ++ -sólo símbolos también. Hay una sección en el estándar C que enumera los nombres reservados para futuras adiciones al estándar. No es una idea completamente estúpida tratar esos nombres como reservados en el espacio de nombres global de C ++ también, pero no es esencial.fuente
<iostream>
,<vector>
,<cstdlib>
, aparte de las que se incluyen la compatibilidad C:<stdint.h>
,<stdlib.h>
. Y sí, la inicialc
indica que<cstdlib>
es el equivalente de C ++ del encabezado estándar de C<stdlib.h>
, en lugar de ser completamente nuevo en C ++ como<vector>
es. Hay un encabezado C ++<complex>
, por lo que tendremos que esperar que ninguna versión futura de C introduzca un encabezado estándar<omplex.h>
.<omplex.h>
, no<complex.h>
. Si se agrega C<omplex.h>
, el equivalente de C ++ sería<complex>
.Incluir las
cstdint
importaciones de los nombres de los símbolos en el espacio de nombres estándar y posiblemente en el espacio de nombres global.Incluir las
stdint.h
importaciones de los nombres de los símbolos en el espacio de nombres global y posiblemente en el espacio de nombres estándar.Las características de la biblioteca estándar de C también se proporcionan en la biblioteca estándar de C ++ y, como convención general de nomenclatura, están precedidas por una c a los nombres correspondientes en la biblioteca estándar de C.
En C ++, deberías usar:
y calificar completamente los nombres de símbolo que usa
std::
mientras está en C, debe usar:
El anexo D (normativo) Características de compatibilidad [depr] establece:
D.6 encabezados de biblioteca estándar de C
Que incluye:
Y además,
fuente
cstdint
es el encabezado C ++ 11,stdint.h
es el encabezado C99 (¡C y C ++ son lenguajes diferentes!)MSVC 2008 no contiene
stdint.h
nicstdint
.Las implementaciones de
cstdint
son en su mayoría simplemente#include <stdint.h>
con algunas correcciones de espacio de nombres / lenguaje.fuente
cstdint
necesita subir las implementaciones al espacio de nombresstd
.stdint.h
. No hay ningún argumento quecstdint
sea un encabezado C ++.stdint.h
que no es parte de C ++ 11. De hecho, es requerido por C ++ 11. Se podría decir "int
está en C ++ 11;long
está en C99; ¡C y C ++ son lenguajes diferentes!", Y ninguna parte de eso tampoco sería falsa. Sin embargo, mi ejemplo es aún más engañoso, ya que C ++ 11 se refiere en parte a C99 para definir el contenido de ambosstdint.h
ycstdint
, pero no se refiere a C para definirloint
.