Novizio programmatore (i) frustrato dalla mancanza di un glossario degli errori del compilatore

65

Un amico della mia famiglia mi ha chiesto un po 'di aiuto mentre impara a programmare (in linguaggio C). Mentre stavamo parlando, ha espresso la frustrazione di avere difficoltà a capire i messaggi di errore che il suo compilatore (GCC) gli sta dando quando commette errori. Non capisce tutti i termini usati, ea volte è la loro combinazione che va oltre la sua comprensione. Mi stava chiedendo "Come mai la documentazione del compilatore non include spiegazioni più lunghe dei messaggi di errore?" - e non ho avuto una buona risposta per lui.

Io stesso - come programmatore più esperto - mi trovo molto raramente in questa situazione, ma quelle rare accadono - un messaggio di errore esotico che non avevo mai incontrato prima. Riesco a cavarmela cercando il messaggio di errore in un motore di ricerca, ma a quanto pare non sempre funziona per lui - soprattutto perché gli errori che incontra sono più comuni e si verificano in più casi distinti, che ha problemi relativi al suo proprio.

Quindi, come dovrebbe un programmatore alle prime armi affrontare la sfida di comprendere i messaggi di errore del compilatore? Nello specifico, con la combinazione di C e GCC?

    
posta einpoklum 18.05.2018 - 20:18
fonte

9 risposte

164

Alcune tecniche utili:

  • Attiva -Wall e -Werror . Potrebbe sembrare controintuitivo quando stai lottando con la decifrazione dei messaggi di errore per creare anche più messaggi di errore, ma gli avvertimenti sono in genere più facili da comprendere e più vicini all'origine effettiva del problema e ignorarli può portare a errori che sono difficili da capire.
  • Basta provare a correggere il primo errore nell'elenco. Spesso gli errori si combinano l'uno con l'altro, portando a successivi messaggi di errore che in realtà non sono veri e propri errori. Correggi uno e ricompila. Otterrai risultati migliori nel correggere più messaggi di errore quando acquisirai più esperienza.
  • Usa la versione più recente del compilatore possibile. C è un linguaggio estremamente stabile. Pertanto, una parte enorme dei miglioramenti apportati ai nuovi compilatori non consiste nell'aggiungere funzionalità linguistiche, ma per migliorare l'esperienza degli sviluppatori, compresi i messaggi di errore migliori. Molte distribuzioni linux ampiamente utilizzate hanno molto vecchie versioni di gcc per impostazione predefinita.
  • Programma in modo incrementale. Non provare a scrivere una tonnellata di codice prima di compilarlo. Scrivi il minor numero possibile che verrà comunque compilato. Se hai modificato solo una riga dall'ultima volta che è stata compilata in modo pulito, è molto più facile capire quale riga contiene il problema reale.
  • Scrivi test unitari. Ti rende più sicuro di apportare modifiche al refactoring durante la correzione degli errori di compilazione.
risposta data 18.05.2018 - 22:09
fonte
56

Il tuo amico non ha bisogno di un glossario. Un glossario non lo aiuterà. Ciò di cui ha bisogno è migliore intuizione su cosa fare quando si verificano errori del compilatore

Gli errori del compilatore C non sono così intuitivi come, ad esempio, errori del compilatore C #, per molte ragioni che hanno a che fare principalmente con la natura "close to the metal" di C. Risoluzione degli errori del compilatore in C non è un esercizio di abbinamento di pattern, perché l'errore che ricevi potrebbe non avere nulla a che fare con il problema reale. A differenza di C # o Java, in cui un messaggio di errore di solito viene mappato su una posizione e un problema precisi del codice, è probabile che gli errori in C siano numerosi e lontani.

Un esempio di questo è "punto e virgola previsto" o qualsiasi numero di errori di sintassi che indicano che il parser è stato bloccato su qualcosa (non necessariamente un punto e virgola). O qualcosa come "dichiarazione anticipata inaspettata", un errore che, quando lo vedo, significa invariabilmente che ho sbagliato la maiuscola in uno dei miei file .h, ma che non punta al file .h come all'origine del problema.

La strategia del tuo amico non dovrebbe essere quella di abbinare questo ad un elenco di errori e soluzioni; dovrebbe essere capire la sintassi e le specifiche del linguaggio C abbastanza bene da capire quale sia il problema attuale .

    
risposta data 18.05.2018 - 20:28
fonte
26

Una tecnica rilevante degna di menzione sta usando un secondo compilatore. Clang ha investito in messaggi di errore migliori, ad esempio, ma qualsiasi modo alternativo di esprimere l'errore può essere illuminante.

Questo è particolarmente vero per il tipo più complesso di errori. Ad esempio, quando si confondono due costrutti simili (non insoliti per i principianti), i compilatori in genere hanno un problema nel generare il giusto messaggio di errore. Ciò può causare confusione quando il compilatore fornisce un messaggio di errore sull'errato utilizzo del costrutto A quando in realtà si intende costruire il costrutto B. Un secondo compilatore potrebbe dedurre che si intendeva B.

    
risposta data 19.05.2018 - 00:42
fonte
12

Qualcuno ha fatto un tentativo di un glossario degli errori GCC su Wikibooks qualche tempo fa, ma sembra che non sia mai decollato e non sia stato aggiornato.

La sezione "Errori" è molto più avanti della sezione "Avvertenze". Sembra che fosse indirizzato al G ++, ma è probabile che ci siano ancora alcune informazioni utili per il tuo amico.

    
risposta data 19.05.2018 - 02:35
fonte
12

Oltre alle risposte di cui sopra, si noti che la maggior parte dei compilatori non hanno glossari di errore completi - questi sarebbero molto lavoro da mantenere in quanto i messaggi stessi spesso cambiano, e ci sono abbastanza un sacco di loro.

Il miglior sostituto per un glossario è l'accesso a Internet. Ogni volta che il compilatore produce un errore che non capisci, conforta che è altamente improbabile che tu sia il primo ad averlo incontrato e sia stato confuso. Un rapido Google del messaggio esatto è spesso sufficiente per fornirti molte informazioni in formato di facile lettura, spesso con un codice di esempio molto simile al tuo.

Oltre a ciò, tempo e familiarità con la lingua e il compilatore sono tutto ciò di cui hai bisogno. Questo e il buon consiglio dato da Karl Bielefeldt .

    
risposta data 19.05.2018 - 03:03
fonte
6

Lo standard C utilizza un numero di termini come "lvalue" e "oggetto" in modi diversi da altri linguaggi di programmazione, e i messaggi del compilatore sono spesso scritti in tali termini. L'uso della terminologia è incoerente in alcune parti dello standard, ma chiunque voglia imparare C dovrebbe esaminare le bozze degli standard C89, C99 e / o C11, nonché i documenti razionali per loro. Ricerca ad es. "C99 draft" o "C89 razionale" dovrebbero funzionare abbastanza bene, anche se potrebbe essere necessario assicurarsi di ottenere il documento che si aspetta. Sebbene la maggior parte dei compilatori supportino lo standard C99, potrebbe essere utile sapere in che modo differisce dallo standard C89, e la motivazione C89 può offrire un background storico che le versioni successive non lo sono.

    
risposta data 19.05.2018 - 01:00
fonte
5

Sono sorpreso che nessuno abbia dato la risposta ovvia e, sospetto, quella più utilizzata nella pratica: non leggere i messaggi di errore.

La stragrande maggioranza del valore della maggior parte dei messaggi di errore è semplicemente che qualcosa non va in questa o quella linea. Il più delle volte guardo il numero della linea e vado su quella linea. La mia "lettura" del messaggio di errore a quel punto di solito è proprio qualunque cosa il mio sguardo catturi di sfuggita, nemmeno una sbavatura. Se non è immediatamente chiaro cosa c'è di sbagliato sopra o vicino alla linea, allora leggerò il messaggio. Questo flusso di lavoro è ancora migliore con un IDE o tooling che evidenzia gli errori sul posto e realizza automaticamente il suggerimento di Karl Bielefeldt di prendere in considerazione solo piccole modifiche.

Naturalmente, i messaggi di errore non puntano sempre sulla riga appropriata, ma spesso non puntano nemmeno alla causa principale appropriata, quindi anche una piena comprensione del messaggio di errore potrebbe essere di aiuto limitato. Non ci vuole molto a farsi un'idea di quali sono i messaggi di errore più affidabili sulla localizzazione della linea corretta.

Da un lato, è probabile che la maggior parte degli errori che un principiante dovrebbe essere dolorosamente ovvi per un programmatore esperto senza l'aiuto del compilatore necessario. D'altra parte, è molto meno probabile che siano così ovvi per i novizi (anche se molti saranno ovvi, la maggior parte degli errori sono errori stupidi). A questo punto sono completamente d'accordo con Robert Harvey, il novizio ha semplicemente bisogno di familiarizzarsi con la lingua. Non si può evitare questo. Errori del compilatore che fanno riferimento a concetti non familiari o sembrano sorprendenti dovrebbero essere visti come suggerimenti per approfondire la conoscenza della lingua. Allo stesso modo per i casi in cui il compilatore si lamenta ma non riesci a capire perché il codice è sbagliato.

Ancora una volta, sono d'accordo con Robert Harvey sul fatto che sia necessaria una strategia migliore per utilizzare gli errori del compilatore. Ho delineato alcuni aspetti sopra e la risposta di Robert Harvey fornisce altri aspetti. Non è nemmeno chiaro cosa speri di fare il tuo amico con un simile "glossario", ed è molto improbabile che un simile "glossario" sia di grande utilità per il tuo amico. I messaggi del compilatore non sono certo il posto giusto per un'introduzione ai concetti del linguaggio 1 e un "glossario" non è tanto un posto migliore per questo. Anche con una descrizione chiara di cosa significa il messaggio di errore, non ti dirà come risolvere il problema.

1 Alcune lingue, come Elm e Dhall (e probabilmente Racket), così come alcune implementazioni linguistiche "orientate ai principianti", tentano di farlo comunque. In questo senso, il consiglio di MSalters di utilizzare una diversa implementazione è direttamente rilevante. Personalmente trovo tali cose non interessanti e non mirate al giusto problema. Questo non vuol dire che non ci siano modi per creare messaggi di errore migliori, ma, per me, tendono a ruotare attorno a rendere più chiare le convinzioni del compilatore e le basi di quelle credenze.

    
risposta data 20.05.2018 - 12:08
fonte
4

So, how should a novice programmer approach the challenge of understanding compiler error messages? Specifically, with the combination of C and GCC?

Dì al tuo amico di fare quanto segue quando incontri un errore che non capiscono:

  • Rimuovi / commenta il codice aggiunto dall'ultima build di successo.
  • Metti piccole parti di esso indietro e compilare
  • Ripeti fino a quando si verifica l'errore

Gli errori del compilatore ti dicono solo ciò che il compilatore non capisce sul tuo codice, non ciò che è sbagliato in esso. Questo approccio impiega all'incirca lo stesso tempo del googling dell'errore e della lettura di alcuni documenti o di un post di StackOverflow, ma offre una comprensione molto migliore di ciò che stai facendo di sbagliato.

Inoltre, fai in modo che vengano compilati spesso fino a quando non iniziano a lavorare su progetti che richiedono pochi minuti per essere costruiti, individuando gli errori prima di aggiungere troppo altro codice.

Infine, dì loro di lavorare su una cosa alla volta, non lavorare su più file senza compilarli in mezzo, non introdurre più dipendenze contemporaneamente, ecc.

    
risposta data 19.05.2018 - 14:35
fonte
4

Un'altra tecnica sarebbe per l'amico di scrivere il proprio glossario nel tempo mentre incontra diversi messaggi di errore. Spesso il modo migliore per imparare qualcosa è insegnarlo. Naturalmente, quando il glossario sarà terminato, probabilmente non ne avrà più bisogno.

La mia esperienza personale con GCC è che ogni messaggio di errore si riferisce a una serie di errori "normali". Ad esempio, quando GCC dice "hai dimenticato il &" di solito significa che ho dimenticato le parentesi. Ovviamente, quali errori corrispondono a quali messaggi di errore dipenderanno dal programmatore, un'altra buona ragione per l'amico di scrivere il proprio glossario.

    
risposta data 20.05.2018 - 15:10
fonte

Leggi altre domande sui tag