2012-11-30 26 views
60

Qual è la differenza tra stdint.h e cstdint?<cstdint> vs <stdint.h>

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 su uno o l'altro?

Il stdint.h definisce ogni tipo senza namespace, i tipi cstdint risiede nella std namespace.

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

cstdint non ha estensione del file e utilizza il prefisso c, stdint.h utilizza l'estensione .h.

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

OS X 10.8 manca ''. Ecco l'errore che ricevo: * './Misc.h: 7: 10: errore fatale: 'cstdint' file non trovato' *. – jww

+2

Correlati: [Quando si usano le intestazioni C in C++, dovremmo usare le funzioni da std :: o dallo spazio dei nomi globale?] (Http://stackoverflow.com/q/32606023/2020827) – sergej

risposta

88

L'intenzione originale in C++ 98 era che si dovrebbe usare <cstdint> in C++, per evitare di inquinare il namespace globale (beh, non <cstdint> in particolare, che viene aggiunto solo in C++ 11, ma il <c*> intestazioni in generale).

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

  • Utilizzare <cstdint> e sia pienamente qualificare ogni tipo integer si usa oppure portarlo in ambito con using std::int32_t; etc (fastidioso perché prolisso, ma è il modo giusto per farlo, proprio come per qualsiasi altro simbolo nella libreria standard C++)
  • Usa <stdint.h> (leggermente male perché sconsigliato)
  • Usa <cstdint> e assumere l'implementazione metterà i simboli nel namespace globale (molto male perché non garantita).

In pratica ho il sospetto che una grande quantità fastidiosa di codice utilizza l'ultima opzione, semplicemente perché è facile da fare per caso su un'implementazione dove <cstdint> mette i simboli nel namespace globale. Dovresti provare a usare il primo. Il secondo ha una virtù, che è garantito per mettere le 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 da using namespace std; che a volte è utile ma ci sono posti che non dovresti mettere il using namespace std;. Persone diverse avranno idee diverse in quei luoghi, ma "al livello più alto in un file di intestazione" è peggio di "al livello più alto in un file cpp", che è peggio di "in un ambito limitato". Alcune persone non scrivono mai using namespace std; affatto.

[*] Ciò significa che le intestazioni standard C++ sono autorizzate a inserire elementi nello spazio dei nomi globale ma non sono obbligati a farlo. Quindi devi evitare di scontrarti con quei simboli, ma non puoi effettivamente usarli perché potrebbero non esserci. 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 sono quasi altrettanto dannose come attaccare using namespace std; al livello più alto in un file di intestazione - la differenza è che le implementazioni lo fanno solo per i simboli nella libreria standard C, mentre using namespace std; lo fa per C++ - anche solo simboli. C'è una sezione nello standard C che elenca i nomi riservati per future aggiunte allo standard. Non è un'idea completamente stupida trattare questi nomi come riservati nello spazio dei nomi globale C++, ma non è essenziale.

+0

L'unica domanda senza risposta che rimane riguarda le convenzioni di denominazione dei file di intestazione, conosci questo argomento? –

+19

@PaperBirdMaster: intestazioni di libreria C++ standard non hanno le estensioni dei file: '', '', '' , oltre a quelli inclusi per la compatibilità C: '', '' . E sì, il 'c' iniziale indica che' 'è l'equivalente di C++ dell'intestazione standard C' ', piuttosto che essere completamente nuovo in C++ come' 'è. C'è un'intestazione C++ '', quindi dovremo solo sperare che nessuna versione futura di C introduca un'intestazione standard ''. –

13

Compresi cstdint importa i nomi dei simboli nel namespace std e possibilmente nel namespace globale.
Compreso stdint.h importa i nomi dei simboli nel namespace globale e possibilmente nello spazio dei nomi std.

Le caratteristiche della libreria standard C sono anche fornite nella libreria standard C++ e come convenzione di denominazione generale sono pre-pended da un c ai nomi corrispondenti nella libreria standard C.

In C++, Si deve usare:

#include <cstdint> 

e completamente qualificare i nomi dei simboli utilizzati con std::
mentre in C, è necessario utilizzare:

#include <stdint.h> 

Allegato D (normativo) Funzionalità di compatibilità [depr] dichiara:

D.6 C libreria standard intestazioni

1 For compatibility with the C standard library and the C Unicode TR, the C++ standard library provides the 25 C headers, as shown in Table 151.

che comprendono:

<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 Every C header, each of which has a name of the form name.h , behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).

3 [ Example: The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std. —end example ]

0
  1. cstdint è C++ 11 intestazione, stdint.h è intestazione C99 (C e C++ sono lingue diverse!)

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

  3. Le implementazioni di cstdint sono in genere semplicemente #include <stdint.h> con alcune correzioni spazio dei nomi/lingua.

+1

3. è sbagliato. 'cstdint' deve sollevare le implementazioni nello spazio dei nomi' std'. –

+0

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

+0

@KonradRudolph, grazie, risolto. –