Jaka jest różnica między stdint.h
i cstdint
?
Oba są dostępne w MSVC (Visual Studio 2010) i gcc-4.5.1. Oba definiują również intX_t
/ uintX_t
types (gdzie X
jest rozmiarem w bajtach typu).
- Jeśli uzasadnienie w obu nagłówkach jest takie samo (typy przenośne), jakie decyzje muszę podjąć, aby zdecydować o jednym lub drugim?
stdint.h
Definiuje każdy typ bez nazw, az cstdint
rodzaje kłamstw w std
przestrzeni nazw.
- Czy jest jakiś powód, aby włączać lub nie uwzględniać zdefiniowanych typów w
std
przestrzeni nazw? Czym się różnią te dwa nagłówki?
cstdint
nie ma rozszerzenia pliku i używa c
przedrostka, stdint.h
używa .h
rozszerzenia.
- Jakie są konwencje nazewnictwa dla tych nagłówków?
c
przedrostek wskazuje, że jest to biblioteka C? istnieje powód braku rozszerzenia pliku wcstdint
?
<cstdint>
. Tutaj jest błąd otrzymuję:./misc.h:7:10: fatal error: 'cstdint' file not found
.Odpowiedzi:
Pierwotnym zamiarem C ++ 98 było to, że powinieneś używać
<cstdint>
w C ++, aby uniknąć zanieczyszczania globalnej przestrzeni nazw (cóż, nie<cstdint>
w szczególności, jest to dodawane tylko w C ++ 11, ale<c*>
ogólnie w nagłówkach).Jednak implementacje i tak upierały się przy umieszczaniu symboli w globalnej przestrzeni nazw, a C ++ 11 ratyfikował tę praktykę [*]. Masz więc zasadniczo trzy opcje:
<cstdint>
i albo w pełni zakwalifikuj każdy typ liczb całkowitych, którego używasz, albo przenieś go do zakresu za pomocąusing std::int32_t;
itp. (Irytujące, ponieważ gadatliwe, ale jest to właściwy sposób, aby to zrobić, tak jak w przypadku każdego innego symbolu w standardowej bibliotece C ++)<stdint.h>
(nieco złe, ponieważ wycofane)<cstdint>
i załóż, że Twoja implementacja umieści symbole w globalnej przestrzeni nazw (bardzo źle, ponieważ nie jest to gwarantowane).W praktyce podejrzewam, że irytująca duża ilość kodu korzysta z ostatniej opcji, po prostu dlatego, że jest to łatwe do zrobienia przez przypadek w implementacji, w której
<cstdint>
symbole są umieszczane w globalnej przestrzeni nazw. Powinieneś spróbować użyć pierwszego. Drugi ma tę zaletę, że gwarantuje umieszczenie rzeczy w globalnej przestrzeni nazw, a nie tylko może to robić. Nie sądzę, żeby to było szczególnie przydatne, ale może zaoszczędzić trochę pisania, jeśli jest to twój priorytet.Jest czwarta opcja,
#include <cstdint>
pousing namespace std;
której czasami jest przydatna, ale są miejsca, w których nie powinieneś umieszczaćusing namespace std;
. Różni ludzie będą mieli różne pomysły, gdzie te miejsca się znajdują, ale „na najwyższym poziomie w pliku nagłówkowym” jest gorsze niż „na najwyższym poziomie w pliku cpp”, co jest gorsze niż „w ograniczonym zakresie”. Niektórzyusing namespace std;
w ogóle nie piszą .[*] Oznacza to, że standardowe nagłówki C ++ mogą umieszczać rzeczy w globalnej przestrzeni nazw, ale nie jest to wymagane. Musisz więc unikać kolizji z tymi symbolami, ale nie możesz ich użyć, ponieważ mogą ich tam nie być. Zasadniczo globalna przestrzeń nazw w C ++ jest polem minowym, staraj się go unikać. Można argumentować, że komitet ratyfikował praktykę poprzez implementacje, która jest prawie tak samo szkodliwa, jak trzymanie się
using namespace std;
na najwyższym poziomie w pliku nagłówkowym - różnica polega na tym, że implementacje robią to tylko dla symboli w standardowej bibliotece C, podczas gdyusing namespace std;
robi to dla C ++ -tylko symbole też. W standardzie C jest sekcja, która zawiera listę nazw zarezerwowanych dla przyszłych dodatków do standardu. Nie jest to całkowicie głupi pomysł, aby traktować te nazwy jako zarezerwowane również w globalnej przestrzeni nazw C ++, ale nie jest to konieczne.źródło
<iostream>
,<vector>
,<cstdlib>
, oprócz tych zawartych w zgodności C:<stdint.h>
,<stdlib.h>
. I tak, inicjałc
wskazuje, że<cstdlib>
jest to odpowiednik C ++ standardowego nagłówka C<stdlib.h>
, a nie zupełnie nowy w C ++, jak<vector>
jest. Istnieje nagłówek C ++<complex>
, więc musimy mieć tylko nadzieję, że żadna przyszła wersja C nie wprowadzi standardowego nagłówka<omplex.h>
.<omplex.h>
, nie<complex.h>
. Gdyby dodano C<omplex.h>
, odpowiednikiem C ++ byłoby<complex>
.Uwzględnienie
cstdint
importuje nazwy symboli w standardowej przestrzeni nazw i prawdopodobnie w globalnej przestrzeni nazw.Uwzględnienie
stdint.h
importuje nazwy symboli w globalnej przestrzeni nazw i prawdopodobnie w standardowej przestrzeni nazw.Funkcje standardowej biblioteki C są również dostępne w C ++ standardowej bibliotece i jako ogólna konwencja nazewnictwa są poprzedzone literą c do odpowiednich nazw w standardowej bibliotece C.
W C ++ powinieneś używać:
#include <cstdint>
iw pełni kwalifikuj nazwy symboli, których używasz
std::
w C, powinieneś używać:
#include <stdint.h>
Załącznik D (normatywny) Cechy zgodności [depr] stwierdza:
D.6 Standardowe nagłówki biblioteki C.
Który zawiera:
I dalej,
źródło
cstdint
to nagłówek C ++ 11,stdint.h
to nagłówek C99 (C i C ++ to różne języki!)MSVC 2008 nie zawiera
stdint.h
anicstdint
.Implementacje
cstdint
są przeważnie#include <stdint.h>
z pewnymi poprawkami dotyczącymi przestrzeni nazw / języka.źródło
cstdint
musi przenieść implementacje do przestrzeni nazwstd
.stdint.h
. Nie ma argumentu, którycstdint
byłby nagłówkiem C ++.stdint.h
nie jest częścią C ++ 11. W rzeczywistości jest to wymagane przez C ++ 11. Można powiedzieć, „int
jest w C ++ 11;long
jest w C99; C i C ++ to różne języki!”, Ale żadna część tego też nie byłaby fałszywa. Mój przykład jest jeszcze bardziej mylący, ponieważ C ++ 11 odwołuje się częściowo do C99, aby zdefiniować zawartość obustdint.h
icstdint
, ale nie odwołuje się do C w celu zdefiniowaniaint
.