2010-03-22 18 views
6

Dopo aver letto diverse domande relative ai problemi con la compilazione (in particolare C++) e notare che in molti casi il problema è un'intestazione mancante #include. Non ho potuto fare a meno di chiedermi nella mia ignoranza e chiedermi (e ora a voi):#include intestazioni in C/C++

Perché le intestazioni mancanti non vengono automaticamente controllate e aggiunte o richieste al programmatore?

Tale funzionalità è disponibile per le istruzioni di importazione Java in Netbeans, ad esempio.

+4

java funziona con i file di intestazione? – Peter

+0

Sono chiamate istruzioni import – bragboy

+2

L'importazione di Java è più simile a 'using' di C++, non come un' # include'. Le dichiarazioni di importazione – fredoverflow

risposta

12

Ricordare lo scontro in Java tra java.util.Date e java.sql.Date? Se qualcuno usa Date nel loro codice, non è possibile sapere se si sono dimenticati di import java.util.Date o import java.sql.Date.

Sia in Java che in C++, non è possibile indicare con certezza quale sia l'istruzione import/include mancante. Quindi nessuna delle due lingue prova. Il tuo IDE potrebbe dare suggerimenti per simboli non dichiarati usati nel tuo codice.

Il problema è ulteriormente complicato in C++, perché lo standard dice che qualsiasi intestazione standard può includere qualsiasi altra intestazione standard. È quindi molto facile usare una funzione o una classe senza includere direttamente l'intestazione che lo definisce, perché il compilatore capita di includere indirettamente l'intestazione giusta.Il codice risultante funziona in alcune implementazioni ma non in altre, a seconda che condividano tale dipendenza dell'intestazione.

Non è in generale possibile per un C++ IDE per dire se una dipendenza intestazione è "garantita", o solo un dettaglio di implementazione incidentale che gli utenti non dovrebbero fare affidamento su. Ovviamente per le librerie standard potrebbe solo sapere cosa viene definito in quali intestazioni, ma non appena si arriva alle librerie di terze parti diventa piuttosto incerto.

Penso che molti programmatori C++ si aspettino di dover cercare quali intestazioni definiscono quali simboli. Con Java, la regola one-public-class-per-file semplifica considerevolmente questo aspetto e si importano semplicemente i pacchetti/le classi che si desidera. Il C++ non ha pacchetti e l'unico modo per l'IDE di trovare una classe chiamata my_namespace::something::MyClass è cercarlo in ogni file di intestazione.

+0

grazie per la spiegazione steve – Carlos

0

NetBeans è un IDE (Integrated Development Environment). Alcuni IDE C/C++ hanno questa caratteristica ... ma non tutti ne sono a conoscenza o li utilizzano.

2

Dal momento che il secondo si fida del computer per pensa a per te, hai un caso maggiore di SkyNet tra le tue mani.

I computer, in generale, sono molto pessimi nel fare scelte, ad eccezione di quelli molto semplici. Tirare fuori qualcosa di dipendenza dall'inferno semplicemente non è un compito che dovresti affidare, perché questo tipo di pensiero porta a codice scomodo e codice buggato.

4

Infine, ricordo che anche Java genera un errore se manca un'istruzione Import. È la GUI di NetBeans che ti semplifica la vita.

Probabilmente dovresti provare a trovare una GUI intelligente per il tuo codice C/C++.

7

Perché le intestazioni mancanti non vengono automaticamente controllate e aggiunte o richieste al programmatore?

Ma sono controllati automaticamente.

  1. Il mio compilatore non riesce a compilare quando non riesce a trovare un'intestazione.
  2. Il mio IDE (eclissi) aggiunge un indizio visivo quando non riesce a trovare un file di intestazione che ho incluso, sottolinea la riga #include e fornisce un suggerimento che mi dice qual è il problema.

Non aggiungerà automaticamente un include perché non può sapere quale include ho dimenticato. I compilatori non sono psichici.

0

Perché in generale è un problema difficile sapere quali file di intestazione è necessario includere per definire qualcosa correttamente. Sarebbe piuttosto una bella caratteristica avere il tuo IDE in grado di indovinare casi semplici e offrire comunque un aiuto.

1

Il compilatore non dovrebbe pensare per te. Cosa succede se c'è una funzione con lo stesso nome in due diverse librerie? Come saprebbe quale intestazione includere e quale libreria collegare? Avere un compilatore o IDE che aggiusta in silenzio il tuo codice sciatto è una cattiva idea secondo me.

1

Parte della differenza è a causa di alcune decisioni di progettazione fondamentali che sono state fatte in modo diverso tra i due. In particolare, Java richiede che il nome di una classe corrisponda al nome del file, quindi il nome della classe che usi più o meno ti dice cosa hai bisogno di importare.

In C o C++, il nome che si assegna a un'intestazione non deve necessariamente corrispondere ai contenuti. Se lo volevi abbastanza, puoi dare un nome alle intestazioni 1.h, 2.h, 3.h, e così via - o anche 1.bas, 2.pas, 3.java, 4.ada, e qualsiasi altra cosa nomi fuorvianti che preferisci. Ovviamente è una pessima idea, ma se lo facessi lo stesso, il compilatore non sarebbe affatto infastidito.

Come tale, è molto più difficile per uno strumento di C++ di indovinare a quale intestazione deve essere incluso per ottenere la definizione di un particolare tipo C o. In teoria, potrebbe (per esempio) costruire un grande database di tutte le funzioni, classi, tipi, ecc., In tutte le intestazioni che hai scritto, e quando ne usi uno, ti dirà quali intestazione (e) definiscono quali nomi , ma non sono a conoscenza di un IDE che effettivamente lo faccia.

2

Se si fa riferimento a una funzione denominata sqrt, in che modo il compilatore riconosce il file in cui cercare se non l'ho specificato? Potrebbe essere assolutamente qualsiasi file sul mio intero disco fisso.

A differenza di Java, C++ in realtà non considera alcun file "speciale". Java ha la sua gigantesca libreria di classi, che viene automaticamente resa accessibile al programmatore.

In C++, questo concetto non esiste. Dì al compilatore quali percorsi cercare, e ogni volta che # include un file, cercherà il nome file in quei percorsi.

Se ciò accade per trovare un file di libreria standard, lo utilizzerà. Se capita di trovare un file di terze parti, lo userà.

Il compilatore non sa che sqrt è definito nell'intestazione math.h. O che è anche tipicamente definito in cmath In effetti, le funzioni definite da un'intestazione potrebbero variare. Forse, se # definisco il simbolo del preprocessore appropriato, alcune funzioni verranno rimosse da un'intestazione specifica e altre saranno abilitate.

Ma a differenza di Java, in cui è possibile determinare le funzioni e le classi definite da una libreria semplicemente esaminando i metadati del file della libreria, in C++, l'intestazione deve essere compilata.E il risultato della sua compilazione potrebbe variare a seconda del contesto in cui è incluso.

Quindi il compilatore C++ non può calcolare a quale intestazione deve essere incluso per definire la funzione appena utilizzata.

+0

grazie amico che ha molto senso – Carlos