<cstdint> vs <stdint.h>


95

Qual'è la differenza tra stdint.he cstdint?

Entrambi sono disponibili in MSVC (Visual Studio 2010) e gcc-4.5.1. Inoltre entrambi definiscono i tipi intX_t/ uintX_t(dove Xè la dimensione in byte del tipo).

  • Se la logica in entrambe le intestazioni è la stessa (tipi portatili), quali decisioni devo prendere per decidere sull'una o sull'altra?

Il stdint.hdefinisce ogni tipo senza alcuno spazio dei nomi, i cstdinttipi si trovano nello stdspazio dei nomi.

  • C'è qualche motivo per includere o non includere i tipi definiti nello stdspazio dei nomi? Cosa c'è di diverso tra le due intestazioni?

cstdintnon ha estensione di file e utilizza il cprefisso, stdint.hutilizza l' .hestensione.

  • Quali sono le convenzioni di denominazione per queste intestazioni? il cprefisso indica che questa è una libreria C? c'è un motivo per la mancanza di estensione del file in cstdint?

OS X 10.8 manca <cstdint>. Ecco l'errore che ricevo: ./misc.h:7:10: fatal error: 'cstdint' file not found.
jww

Risposte:


122

L'intenzione originale in C ++ 98 era che dovresti usare <cstdint>in C ++, per evitare di inquinare lo spazio dei nomi globale (beh, non <cstdint>in particolare, viene aggiunto solo in C ++ 11, ma le <c*>intestazioni in generale).

Tuttavia, le implementazioni persistevano comunque nel mettere i simboli nello spazio dei nomi globale e C ++ 11 ha ratificato questa pratica [*]. Quindi, fondamentalmente hai tre opzioni:

  • Usa <cstdint>e qualifica completamente ogni tipo di intero che usi oppure portalo nell'ambito con using std::int32_t;ecc (fastidioso perché prolisso, ma è il modo giusto per farlo proprio come per qualsiasi altro simbolo nella libreria standard C ++)
  • Usa <stdint.h>(leggermente scadente perché deprecato)
  • Usa <cstdint>e presumi che la tua implementazione metta i simboli nello spazio dei nomi globale (pessimo perché non garantito).

In pratica sospetto che una fastidiosa grande quantità di codice utilizzi l'ultima opzione, semplicemente perché è facile farlo per sbaglio su un'implementazione in cui <cstdint>mette i simboli nel namespace globale. Dovresti provare a usare il primo. Il secondo ha una virtù, che è garantito mettere cose nello spazio dei nomi globale invece di farlo solo forse. Non penso che sia particolarmente utile, ma potrebbe risparmiare un po 'di digitazione se questa è la tua priorità.

C'è una quarta opzione, #include <cstdint>seguita dalla using namespace std;quale a volte è utile, ma ci sono posti in cui non dovresti mettere il file using namespace std;. Persone diverse avranno idee diverse su dove siano quei posti, ma "al livello più alto in un file di intestazione" è peggio di "al livello superiore in un file cpp", che è peggio che "in un ambito limitato". Alcune persone non scrivono mai using namespace std;.

[*] Ciò significa che le intestazioni standard C ++ possono inserire cose nello spazio dei nomi globale ma non è obbligatorio. Quindi devi evitare di entrare in collisione con quei simboli, ma non puoi effettivamente usarli perché potrebbero non essere lì. Fondamentalmente, lo spazio dei nomi globale in C ++ è un campo minato, cerca di evitarlo. Si potrebbe obiettare che il comitato ha ratificato una pratica con implementazioni che è dannosa quasi quanto using namespace std;rimanere al livello più alto in un file di intestazione - con la differenza che le implementazioni lo fanno solo per i simboli nella libreria standard C, mentre lo using namespace std;fa per C ++ -solo anche simboli. C'è una sezione nello standard C che elenca i nomi riservati per future aggiunte allo standard. Non è un'idea completamente stupida trattare quei nomi come riservati anche nello spazio dei nomi globale C ++, ma non è essenziale.


L'unica domanda senza risposta che rimane è sulle convenzioni di denominazione dei file di intestazione, conosci questo argomento?
PaperBirdMaster

24
@PaperBirdMaster: C ++ intestazioni libreria standard non hanno le estensioni dei file: <iostream>, <vector>, <cstdlib>, oltre a quelli inclusi per la compatibilità C: <stdint.h>, <stdlib.h>. E sì, l'iniziale cindica che <cstdlib>è l'equivalente di C ++ dell'intestazione standard C <stdlib.h>, piuttosto che essere completamente nuovo per C ++ come lo <vector>è. C'è un'intestazione C ++ <complex>, quindi dobbiamo solo sperare che nessuna versione futura di C introduca un'intestazione standard <omplex.h>.
Steve Jessop

@SteveJessop Erm, C99?
SS Anne

1
@ JL2210 nota che ha detto di <omplex.h>no <complex.h>. Se si aggiunge C <omplex.h>, l'equivalente C ++ sarebbe <complex>.
John Leuenhagen

16

L'inclusione cstdintimporta i nomi dei simboli nello spazio dei nomi std e possibilmente nello spazio dei nomi globale.
L'inclusione stdint.himporta i nomi dei simboli nello spazio dei nomi Global e possibilmente nello spazio dei nomi std.

Le funzionalità della libreria standard C sono fornite anche nella libreria standard C ++ e come convenzione di denominazione generale sono anteposte da una c ai nomi corrispondenti nella libreria standard C.

In C ++, dovresti usare:

#include <cstdint>

e qualifica completamente i nomi dei simboli che usi std::
mentre sei in C, dovresti usare:

#include <stdint.h>

L'allegato D (normativo) Caratteristiche di compatibilità [depr] afferma:

D.6 Intestazioni della libreria standard C.

1 Per compatibilità con la libreria standard C e C Unicode TR, la libreria standard C ++ fornisce le 25 intestazioni C, come mostrato nella Tabella 151.

Che include:

<assert.h> <float.h> <math.h> <stddef.h> <tgmath.h> <complex.h> <inttypes.h> <setjmp.h> <stdio.h> <time.h> <ctype.h> <iso646.h> <signal.h> <stdint.h> <uchar.h> <errno.h> <limits.h> <stdarg.h> <stdlib.h> <wchar.h> <fenv.h> <locale.h> <stdbool.h> <string.h> <wctype.h>

E inoltre,

2 Ogni intestazione C, ciascuna delle quali ha un nome del modulo name.h, si comporta come se ogni nome collocato nello spazio dei nomi della libreria standard dal corrispondente cname headerfosse inserito nell'ambito dello spazio dei nomi globale. Non è specificato se questi nomi vengono prima dichiarati o definiti all'interno dell'ambito dello spazio dei nomi (3.3.6) dello spazio dei nomi std e vengono poi iniettati nell'ambito dello spazio dei nomi globale mediante dichiarazioni using esplicite (7.3.3).

3 [Esempio: l'intestazione <cstdlib>fornisce sicuramente le sue dichiarazioni e definizioni all'interno dello spazio dei nomi std. Può anche fornire questi nomi all'interno dello spazio dei nomi globale. L'intestazione <stdlib.h>fornisce sicuramente le stesse dichiarazioni e definizioni all'interno dello spazio dei nomi globale, proprio come nello standard C. Può anche fornire questi nomi all'interno dello spazio dei nomi std. —End esempio]


-1
  1. cstdintè l'intestazione C ++ 11, stdint.hè l'intestazione C99 (C e C ++ sono linguaggi diversi!)

  2. MSVC 2008 non contiene né stdint.hcstdint.

  3. Le implementazioni di cstdintsono per lo più semplicemente #include <stdint.h>con alcune correzioni di spazio dei nomi / lingua.


2
3. è sbagliato. cstdintha bisogno di issare le implementazioni nello spazio dei nomi std.
Konrad Rudolph

1
1. è anche sbagliato, stdint.h è definito come parte della libreria C ++ nell'Allegato D normativo dello standard C ++.
freddo il

@chill, potresti fornire il link all'Allegato D? Qui en.cppreference.com/w/cpp/types/integer afferma che è l'intestazione C ++ 11.
hate-engine il

1
@ hate-engine, ti suggerisco di cercarlo nella tua copia dello standard C ++. Quella pagina di riferimento non menziona stdint.h. Non c'è argomento che cstdintsia un'intestazione C ++.
freddo il

2
Nessuna parte di 1. è falsa, è solo che presa insieme sembra che tu stia dicendo che stdint.hnon fa parte di C ++ 11. Infatti è richiesto da C ++ 11. Si potrebbe dire " intè in C ++ 11; longè in C99; C e C ++ sono linguaggi diversi!", E nemmeno una parte di questo sarebbe falsa. Il mio esempio è ancora più fuorviante, tuttavia, poiché C ++ 11 si riferisce in parte a C99 per definire il contenuto di entrambi stdint.he cstdint, ma non si riferisce a C per definire int.
Steve Jessop
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.