Come mai i compilatori sono così affidabili?


64

Usiamo i compilatori su base giornaliera come se la loro correttezza sia data, ma anche i compilatori sono programmi e possono potenzialmente contenere bug. Mi sono sempre chiesto di questa infallibile robustezza. Hai mai riscontrato un bug nel compilatore stesso? Cos'è stato e come hai capito che il problema era nel compilatore stesso?

... e come fanno fanno compilatori così affidabile?


16
Bene, compilano il compilatore in esso ...
Michael K,

31
Non sono infallibili. Ci sono bug del compilatore - è solo che sono molto rari.
ChrisF

5
I bug diventano più rari man mano che si scende lo stack di codice: i bug dell'applicazione sono più comuni dei bug del compilatore. I bug del compilatore sono più comuni dei bug della CPU (microcodice). Questa è in realtà una buona notizia: puoi immaginare se fosse il contrario?
Fixee,

Si potrebbe imparare qualcosa osservando come un compilatore che fa un sacco di bug (come SDCC!) È diverso da un compilatore come gcc che è molto più robusto e affidabile.
Ben Jackson,

Risposte:


97

Vengono testati a fondo tramite l'utilizzo da parte di migliaia o addirittura milioni di sviluppatori nel tempo.

Inoltre, il problema da risolvere è ben definito (da una specifica tecnica molto dettagliata). E la natura dell'attività si presta facilmente ai test unitari / di sistema. Cioè sta fondamentalmente traducendo l'input testuale in un formato molto specifico per l'output in un altro tipo di formato ben definito (una sorta di bytecode o codice macchina). Quindi è facile creare e verificare casi di test.

Inoltre, di solito anche i bug sono facili da riprodurre: a parte le informazioni esatte sulla versione della piattaforma e del compilatore, di solito tutto ciò che serve è un pezzo di codice di input. Per non parlare del fatto che gli utenti del compilatore (essendo essi stessi sviluppatori) tendono a fornire segnalazioni di bug molto più precise e dettagliate rispetto a qualsiasi utente medio di computer :-)


32
Inoltre gran parte del codice del compilatore può essere probabilmente dimostrato corretto.
biziclop,

@biziclop, buon punto, questa è un'altra conseguenza della natura speciale dell'attività.
Péter Török,

Il primo compilatore completo è stato scritto nel 1957 per la lingua FORTRAN da John Backus. Quindi, vedete, la tecnologia del compilatore ha più di 50 anni. Abbiamo avuto un po 'di tempo per farlo bene anche se, come altri sottolineano, i compilatori hanno dei bug.
leed25d

@biziclop, infatti, alcuni componenti come i lexer e i parser possono anche essere autogenerati da una grammatica, il che riduce di nuovo il rischio di bug (a condizione che il generatore di lexer / parser sia robusto, cosa che di solito lo è, per lo stesso motivo elencato sopra) .
Péter Török,

2
@Péter: i generatori di Lexer / parser sembrano essere piuttosto rari nei compilatori più usati - la maggior parte scrive a mano lexer e il parser per vari motivi, tra cui la velocità e la mancanza di generatori di parser / lexer sufficientemente intelligenti per il linguaggio in questione (ad es. C ).

61

Oltre a tutte le grandi risposte finora:

Hai un "pregiudizio dell'osservatore". Non osservi i bug e quindi presumi che non ce ne siano.

Pensavo come te. Poi ho iniziato a scrivere compilatori in modo professionale, e lascia che te lo dica, ci sono molti bug lì dentro!

Non vedi i bug perché scrivi codice che è proprio come il 99,999% di tutto il resto del codice che la gente scrive. Probabilmente scrivi un codice perfettamente normale, semplice e chiaramente corretto che chiama metodi ed esegue cicli e non fa nulla di strano o di strano, perché sei uno sviluppatore normale che risolve i normali problemi aziendali.

Non vedi alcun bug del compilatore perché i bug del compilatore non sono negli scenari di codice normale semplici da analizzare; i bug sono nell'analisi di codice strano che non si scrive.

Io d'altra parte ho il pregiudizio opposto dell'osservatore. Vedo codice pazzo tutto il giorno ogni giorno, e quindi per me i compilatori sembrano essere pieni di bug.

Se ti sei seduto con le specifiche del linguaggio di qualsiasi lingua e hai preso l'implementazione di un compilatore per quella lingua, e hai davvero cercato di determinare se il compilatore ha implementato esattamente la specifica o meno, concentrandoti su casi angolari oscuri, molto presto ti accorgeresti bug del compilatore abbastanza frequentemente. Lascia che ti faccia un esempio, ecco un bug del compilatore C # che ho trovato letteralmente cinque minuti fa.

static void N(ref int x){}
...
N(ref 123);

Il compilatore fornisce tre errori.

  • Un argomento ref o out deve essere una variabile assegnabile.
  • La migliore corrispondenza per N (ref int x) ha argomenti non validi.
  • "Ref" mancante sull'argomento 1.

Ovviamente il primo messaggio di errore è corretto e il terzo è un bug. L'algoritmo di generazione dell'errore sta cercando di capire perché il primo argomento non è valido, lo osserva, vede che è una costante e non torna al codice sorgente per verificare se è stato contrassegnato come "ref"; piuttosto, presume che nessuno sarebbe abbastanza sciocco da contrassegnare una costante come ref e decide che l'arbitro debba mancare.

Non è chiaro quale sia il terzo messaggio di errore corretto, ma non è così. In effetti, non è chiaro se il secondo messaggio di errore sia corretto. La risoluzione del sovraccarico dovrebbe fallire o "ref 123" dovrebbe essere trattato come un argomento ref del tipo corretto? Ora dovrò pensarci e parlarne con il team di triage in modo che possiamo determinare quale sia il comportamento corretto.

Non hai mai visto questo bug perché probabilmente non avresti mai fatto qualcosa di così sciocco da provare a passare 123 con ref. E se lo facessi, probabilmente non noteresti nemmeno che il terzo messaggio di errore è privo di senso, poiché il primo è corretto e sufficiente per diagnosticare il problema. Ma provo a fare cose del genere, perché sto cercando di interrompere il compilatore. Se ci provassi, vedresti anche i bug.


4
Buoni messaggi di errore dopo il primo sono molto difficili da fare.

Certo, ci deve essere energia spesa meglio quindi rendere i compilatori completamente "stupidi" :)
Homde,

2
@MKO: Certo. Molti bug non vengono corretti. A volte la correzione è così costosa e lo scenario è così oscuro che il costo non è giustificato dai benefici. E a volte abbastanza persone sono arrivate a fare affidamento sul comportamento "buggy" che devi mantenere.
Eric Lippert

mmm ... i bug che finiscono nei messaggi di errore vanno bene. È sempre possibile manipolare un po 'il codice per farlo funzionare. Che dire dei bug in cui il compilatore accetta il codice sorgente e produce un output "errato" in modo sicuro. È spaventoso
Gianluca Ghettini,

7
@aij: Corretto nel senso di "codice C # chiaramente legale". Ad esempio, hai mai scritto un programma contenente un'interfaccia che ha ereditato due interfacce in cui un'interfaccia aveva una proprietà e l'altra aveva un metodo con lo stesso nome della proprietà? Veloce, senza guardare le specifiche: è legale ? Supponiamo ora di avere una chiamata a quel metodo; è ambiguo ? E così via. Le persone scrivono codice che non fa sempre ciò che significano. Ma raramente scrivono codice in cui dovresti essere un esperto di specifiche per dire se è anche C # legale.
Eric Lippert,

52

Ma stai scherzando? Anche i compilatori hanno bug, carichi davvero.

GCC è probabilmente il più celebre compilatore open source del pianeta e dai un'occhiata al suo database di bug: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=-- -

Tra GCC 3.2 e GCC 3.2.3 dai un'occhiata a quanti bug sono stati corretti: http://gcc.gnu.org/gcc-3.2/changes.html

Per quanto riguarda altri come Visual C ++, non voglio nemmeno iniziare.

Come si rendono affidabili i compilatori? Bene, per cominciare hanno un sacco di test unitari. E l'intero pianeta li usa, quindi nessuna mancanza di tester.

Scherzi a parte, gli sviluppatori di compilatori che mi piace credere siano programmatori di livello superiore e, sebbene non siano infallibili, hanno un bel pugno.


19

Ne ho incontrati due o tre ai miei tempi. L'unico vero modo per rilevarne uno è guardare il codice assembly.

Sebbene i compilatori siano altamente affidabili per i motivi segnalati da altri poster, penso che l'affidabilità del compilatore sia spesso una valutazione che si autoavvera. I programmatori tendono a vedere il compilatore come standard. Quando qualcosa va storto, si presume che sia colpa tua (perché il 99,999% delle volte è) e si modifica il codice per aggirare il problema del compilatore anziché viceversa. Ad esempio, l'arresto anomalo del codice con un'impostazione di ottimizzazione elevata è sicuramente un bug del compilatore, ma la maggior parte delle persone lo imposta un po 'più in basso e va avanti senza segnalare il bug.


6
+1 per "visualizzare il compilatore come standard". Ho a lungo sostenuto che ci sono due cose che definiscono veramente una lingua: il compilatore e la libreria standard. Un documento standard è solo documentazione.
Mason Wheeler,

8
@ Mason: Funziona bene con le lingue con un'unica implementazione. Per le lingue con molti, lo standard è di vitale importanza. L'impatto nella vita reale è che, se ti lamenti di qualcosa, il fornitore ti prenderà sul serio se si tratta di un problema di standard e ti spazzerà via se è un comportamento indefinito o qualcosa del genere.
David Thornley,

2
@ Mason - Questo è solo perché così poche lingue hanno uno standard e / a cui rispettano. Questo, a proposito, IMHO, non è una buona cosa - per qualsiasi tipo di sviluppo serio, che dovrebbe durare più di una generazione di SO.
Arriva il

1
@ David: o più precisamente, un'implementazione dominante . Borland definisce Pascal e Microsoft definisce C # indipendentemente da ciò che dicono ANSI ed ECMA.
dan04,

4
L'arresto anomalo del codice C, C ++ o Fortran con un'ottimizzazione elevata è molto più spesso un codice di input errato rispetto ai bug del compilatore. Lavoro molto spesso con compilatori recenti e pre-release, spesso per hardware molto nuovo, e vedo regolarmente errori associati all'ottimizzazione. Poiché questi linguaggi hanno nozioni di comportamento indefinito e non specificano la gestione di programmi non conformi, è necessario controllare gli arresti anomali abbastanza attentamente, eventualmente contro l'assemblaggio. Nell'80-90% dei casi, il codice dell'applicazione è errato e non il compilatore.
Phil Miller,

14

I compilatori hanno diverse proprietà che portano alla loro correttezza:

  • Il dominio è molto conosciuto e studiato. Il problema è ben definito e le soluzioni offerte sono ben definite.
  • Il test automatico è sufficiente per dimostrare che i compilatori funzionano correttamente
  • I compilatori hanno test molto ampi, generalmente pubblici, automatizzati e unitari, che si sono accumulati nel tempo per coprire più spazio di errore rispetto alla maggior parte degli altri programmi
  • I compilatori hanno un gran numero di bulbi oculari che guardano i loro risultati

2
Inoltre, in molti casi il codice è vecchio, GCC ha ben più di 20 anni, così come molti altri, quindi molti bug sono stati risolti da molto tempo.
Zaccaria K

13

Usiamo compilatori su base giornaliera

... e come rendono i compilatori così affidabili?

Non lo fanno. Noi facciamo. Poiché tutti li usano sempre, i bug vengono rilevati rapidamente.

È un gioco di numeri. Perché compilatori si abitua così pervasivamente, è altamente probabile che qualsiasi bug sarà essere innescato da qualcuno, ma perché c'è un gran numero di utenti tale, è altamente improbabile che quel qualcuno sarà specificamente.

Quindi, dipende dal tuo punto di vista: tra tutti gli utenti, i compilatori sono buggy. Ma è molto probabile che qualcun altro abbia compilato un pezzo di codice simile prima di te, quindi se il loro fosse un bug, li avrebbe colpiti, non tu, quindi dal tuo punto di vista individuale , sembra che il bug fosse mai lì.

Naturalmente, in aggiunta, puoi aggiungere tutte le altre risposte qui: i compilatori sono ben studiati, ben compresi. C'è questo mito che sono difficili da scrivere, il che significa che solo i programmatori molto intelligenti e molto bravi in ​​realtà tentano di scriverne uno e sono molto attenti quando lo fanno. Sono generalmente facili da testare e facili da stress test o fuzz test. Gli utenti del compilatore tendono ad essere programmatori esperti stessi, portando a segnalazioni di bug di alta qualità. E viceversa: gli autori di compilatori tendono ad essere utenti del proprio compilatore.


11

Oltre a tutte le risposte, vorrei aggiungere:

Io credo che un sacco di volte, i venditori stanno mangiando il loro cibo per cani. Significato, stanno scrivendo i compilatori in se stessi.


7

Mi sono imbattuto spesso in bug del compilatore.

Li puoi trovare negli angoli più bui dove ci sono meno tester. Ad esempio, per trovare bug in GCC dovresti provare:

  • Crea un cross-compilatore. Troverai letteralmente dozzine di bug negli script di configurazione e creazione di GCC. Alcuni si traducono in errori di compilazione durante la compilazione di GCC e altri in errori nella compilazione incrociata per la compilazione di eseguibili funzionanti.
  • Costruisci una versione Itanium di GCC usando profile-bootstrap. L'ultima volta che l'ho provato su GCC 4.4 e 4.5 non è riuscito a produrre un gestore di eccezioni C ++ funzionante. La build non ottimizzata ha funzionato bene. Nessuno sembrava interessato a correggere il bug che ho segnalato e ho rinunciato a risolverlo da solo dopo aver cercato di scavare in ciò che stava rompendo nelle specifiche della memoria asm GCC.
  • Prova a costruire il tuo GCJ funzionante dalle ultime cose senza seguire uno script di build distro. Ti sfido.

Troviamo molti problemi con IA64 (Itanium). Non abbiamo molti clienti per quella piattaforma, quindi ridurre il livello di ottimizzazione è il nostro solito bugfix. Questo torna alle altre risposte, i compilatori di lingue popolari per architetture popolari di solito hanno avuto abbastanza visibilità da parte dell'utente e supporto sufficiente per essere abbastanza bravi, ma mentre vai alle architetture e / o lingue meno popolari dovresti aspettarti che l'affidabilità ne risenta.
Omega Centauri,

@Omega: ridurre l'ottimizzazione sembra essere quello che fanno tutti. Sfortunatamente, Itanium richiede compilatori ad alta ottimizzazione per funzionare bene. Oh bene ...
Zan Lynx,

Ti sento. Francamente l'architettura era già obsoleta quando è uscita, fortunatamente AMD ha forzato la mano di Intels con x86-64 (che disprezza le sue molte verruche non è poi così male). Se riesci a spezzare i tuoi file di origine, potresti essere in grado di isolare il problema (i) e trovare una soluzione alternativa. Questo è quello che facciamo se si tratta di una piattaforma importante, ma non per IA64.
Omega Centauri,

@Omega: purtroppo mi piace molto Itanium. È un'architettura meravigliosa. Considero x86 e x86-64 obsoleti, ma ovviamente non moriranno mai.
Zan Lynx,

L'x86 è un po 'strano. Continuano ad aggiungere nuove cose, quindi cresce una verruca alla volta. Tuttavia, il motore di esecuzione fuori servizio funziona abbastanza bene e il nuovo materiale SSE => AVX offre alcune reali capacità a coloro che sono disposti a codificarlo. Certo, ci sono molti transistor dedicati a fare cose semi-obsolete, ma questo è un prezzo che si paga per la compatibilità legacy.
Omega Centauri,

5

Diverse ragioni:

  • Gli autori di compilatori " mangiano il proprio cibo per cani ".
  • I compilatori si basano su principi ben noti di CS.
  • I compilatori sono costruiti secondo una specifica molto chiara .
  • I compilatori vengono testati .
  • I compilatori non sono sempre molto affidabili .

4

Di solito sono molto bravi a -O0. In effetti, se sospettiamo un bug del compilatore, confrontiamo -O0 rispetto a qualsiasi livello che stiamo cercando di usare. Livelli di ottimizzazione più elevati comportano un rischio maggiore. Alcuni lo sono persino deliberatamente, ed etichettati come tali nella documentazione. Ne ho incontrati molti (almeno cento durante il mio tempo), ma recentemente stanno diventando molto più rari. Tuttavia, alla ricerca di buoni numeri di marchio (o di altri parametri di riferimento importanti per il marketing), la tentazione di spingere i limiti è grande. Qualche anno fa abbiamo avuto problemi in cui un fornitore (per non nominare) ha deciso di rendere predefinita la violazione della parentesi, piuttosto che qualche opzione di compilazione chiaramente etichettata.

Può essere difficile diagnosticare un errore del compilatore rispetto a dire un riferimento di memoria vagante, una ricompilazione con diverse opzioni può semplicemente confondere il posizionamento relativo degli oggetti dati all'interno della memoria, quindi non sai se si tratta di Heisenbug del codice sorgente o di un buggy compilatore. Inoltre, molte ottimizzazioni apportano modifiche legittime all'ordine delle operazioni o anche semplificazioni algebriche della tua algebra, e queste avranno proprietà diverse rispetto all'arrotondamento in virgola mobile e under / overflow. È difficile districare questi effetti dai bug REALI. Il calcolo a virgola mobile hard core è difficile per questo motivo, poiché i bug e la sensibilità numerica spesso non sono facili da districare.


4

I bug del compilatore non sono poi così rari. Il caso più comune è che un compilatore riporti un errore sul codice che dovrebbe essere accettato o che un compilatore accetti il ​​codice che avrebbe dovuto essere rifiutato.


sfortunatamente non possiamo vedere la seconda classe di bug: il codice viene compilato = va tutto bene. Quindi probabilmente la metà dei bug (ipotizzando un rapporto di divisione di 50-50 tra le due classi di bug) non viene trovata dalle persone, ma per mezzo dei test dell'unità del compilatore
Gianluca Ghettini,

3

Sì, ho riscontrato un bug nel compilatore ASP.NET proprio ieri:

Quando si utilizzano modelli fortemente tipizzati nelle viste, esiste un limite al numero di parametri che i modelli possono contenere. Ovviamente non possono essere necessari più di 4 parametri di template, quindi entrambi gli esempi seguenti rendono troppo complicato il compilatore:

ViewUserControl<System.Tuple<type1, type2, type3, type4, type5>>

Non verrà compilato così com'è ma lo sarà se type5viene rimosso.

ViewUserControl<System.Tuple<MyModel, System.Func<type1, type2, type3, type4>>>

Compilerebbe se type4viene rimosso.

Nota che System.Tupleha molti sovraccarichi e può richiedere fino a 16 parametri (è pazzesco lo so).


3

Hai mai riscontrato un bug nel compilatore stesso? Cos'è stato e come hai capito che il problema era nel compilatore stesso?

Sì!

I due più memorabili sono stati i primi due che abbia mai incontrato. Erano entrambi nel compilatore Lightspeed C per Mac 680x0 tra il 1985 e il 2007.

Il primo è stato in cui, in alcune circostanze, l'operatore di postincremento intero non ha fatto nulla - in altre parole, in un particolare pezzo di codice, "i ++" semplicemente non ha fatto nulla per "i". Mi stavo strappando i capelli finché non ho visto uno smontaggio. Quindi ho fatto l'incremento in un modo diverso e ho inviato una segnalazione di bug.

Il secondo era un po 'più complicato ed era davvero una "caratteristica" poco considerata che andava male. I primi Mac avevano un sistema complicato per eseguire operazioni su disco di basso livello. Per qualche ragione che non ho mai capito - probabilmente a che fare con la creazione di eseguibili più piccoli - piuttosto che il compilatore semplicemente generando le istruzioni di funzionamento del disco sul posto nel codice oggetto, il compilatore Lightspeed chiamerebbe una funzione interna, che in fase di esecuzione ha generato l'operazione del disco istruzioni in pila e saltò lì.

Funzionava perfettamente su 68000 CPU, ma quando si eseguiva lo stesso codice su una CPU 68020, spesso faceva cose strane. Si è scoperto che una nuova funzionalità del 68020 era una cache di istruzioni a 256 byte per l'istruzione primitiva. In questi primi tempi con cache della CPU, non aveva la nozione che la cache fosse "sporca" e necessitava di essere riempita di nuovo; Immagino che i progettisti di CPU di Motorola non abbiano pensato al codice di auto-modifica. Quindi, se hai eseguito due operazioni su disco abbastanza vicine tra loro nella sequenza di esecuzione e il runtime di Lightspeed ha creato le istruzioni effettive nella stessa posizione nello stack, la CPU penserebbe erroneamente di avere un hit nella cache delle istruzioni ed eseguire la prima operazione su disco due volte.

Ancora una volta, capire che ci voleva un po 'di tempo per scavare con un disassemblatore e un sacco di passaggi singoli in un debugger di basso livello. La mia soluzione è stata quella di anteporre a ogni operazione del disco una chiamata a una funzione che eseguiva 256 istruzioni "NOP", che inondava (e quindi svuotava) la cache delle istruzioni.

Da allora, nel corso dei 25 anni, ho visto sempre meno bug nel compilatore. Penso che ci siano un paio di ragioni per questo:

  • Esiste una serie sempre crescente di test di convalida per i compilatori.
  • I compilatori moderni sono in genere divisi in due o più parti, una delle quali genera codice indipendente dalla piattaforma (ad esempio, LLVM mira a ciò che potresti considerare una CPU immaginaria) e un'altra che lo traduce in istruzioni per l'hardware di destinazione reale. Nei compilatori multipiattaforma, la prima parte viene utilizzata ovunque, quindi ottiene tonnellate di test nel mondo reale.

Uno dei motivi per evitare il codice automodificante.
Technophile,

3

Trovato un evidente errore in Turbo Pascal 5,5 anni fa. Errore presente nella versione precedente (5.0) o successiva (6.0) del compilatore. E uno che avrebbe dovuto essere facile da testare, in quanto non era affatto una maiuscola (solo una chiamata che non è quella comunemente usata).

In generale, certamente i costruttori di compilatori commerciali (piuttosto che i progetti di hobby) avranno in atto procedure di controllo qualità e test molto estese. Sanno che i loro compilatori sono i loro progetti di punta e che i difetti avranno un aspetto molto brutto su di loro, peggio di quanto sembrerebbero su altre società che producono la maggior parte degli altri prodotti. Gli sviluppatori di software sono un gruppo che non perdona, i nostri fornitori di strumenti ci deludono probabilmente cercheremo alternative piuttosto che aspettare una soluzione dal fornitore, e molto probabilmente comunicheremo questo fatto ai nostri colleghi che potrebbero benissimo seguire il nostro esempio. In molti altri settori non è così, quindi la potenziale perdita per un produttore di compilatori a causa di un grave bug è di gran lunga superiore a quella di un produttore di software di editing video.


2

Quando il comportamento del tuo software è diverso quando compilato con -O0 e -O2, hai trovato un bug del compilatore.

Quando il comportamento del tuo software è solo diverso da quello che ti aspetti, è probabile che il bug sia nel tuo codice.


8
Non necessariamente. In C e C ++, c'è una quantità fastidiosa di comportamento non specificato e indefinito, che può legittimamente variare in base al livello di ottimizzazione o alla fase lunare o al movimento degli indici di Dow Jones. Quel test funziona in linguaggi più strettamente definiti.
David Thornley,

2

Si verificano errori del compilatore, ma tendi a trovarli in angoli strani ...

C'è stato uno strano bug nel compilatore VAX VMS C della Digital Equipment Corporation negli anni '90

(Indossavo una cipolla sulla cintura, come era la moda all'epoca)

Un punto e virgola estraneo che precede un ciclo for dovrebbe essere compilato come il corpo del ciclo for.

f(){...}
;
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++){
     puts("hello");
  }
}

Sul compilatore in questione, il ciclo viene eseguito solo una volta.

vede

f(){...}
g(){...}

void test(){
  int i;
  for ( i=0; i < 10; i++) ;  /* empty statement for fun */

  {
     puts("hello");
  }
}

Mi è costato molto tempo.

La versione precedente del compilatore PIC C che noi (eravamo soliti) infliggere agli studenti di esperienza lavorativa non era in grado di generare codice che utilizzava correttamente l'interruzione ad alta priorità. Hai dovuto aspettare 2-3 anni e aggiornare.

Il compilatore MSVC 6 aveva un bug elegante nel linker, si sarebbe verificato un errore di segmentazione e sarebbe morto di tanto in tanto senza motivo. Una build pulita generalmente lo risolveva (ma sospiro non sempre).


2

In alcuni domini, come il software avionico, vi sono requisiti di certificazione estremamente elevati, sia sul codice che sull'hardware, nonché sul compilatore. A proposito di quest'ultima parte, esiste un progetto che mira a creare un compilatore C formalmente verificato, chiamato Compcert . In teoria, questo tipo di compilatore è affidabile come viene.


1

Ho visto diversi bug del compilatore, ne ho riportati alcuni me stesso (in particolare, in F #).

Detto questo, penso che i bug del compilatore siano rari perché le persone che scrivono compilatori sono generalmente molto a proprio agio con i concetti rigorosi dell'informatica che li rendono davvero consapevoli delle implicazioni matematiche del codice.

Molti di loro presumibilmente hanno molta familiarità con cose come il calcolo lambda, la verifica formale, la semantica denotazionale ecc. - cose che un programmatore medio come me riesce a malapena a comprendere.

Inoltre, di solito esiste una mappatura abbastanza semplice dall'input all'output nei compilatori, quindi il debug di un linguaggio di programmazione è probabilmente molto più semplice del debug, diciamo, di un motore di blog.


1

Ho trovato un bug nel compilatore C # non molto tempo fa, puoi vedere come Eric Lippert (che è nel team di progettazione C #) ha capito quale fosse il bug qui .

Oltre alle risposte già fornite, vorrei aggiungere alcune altre cose. I progettisti di compilatori sono spesso programmatori estremamente bravi. I compilatori sono molto importanti: la maggior parte della programmazione viene eseguita utilizzando i compilatori, quindi è indispensabile che il compilatore sia di alta qualità. È quindi nel migliore interesse delle aziende che producono compilatori metterci le persone migliori (o almeno, molto brave: ai migliori potrebbe non piacere la progettazione di compilatori). Microsoft vorrebbe che i compilatori C e C ++ funzionassero correttamente, altrimenti il ​​resto dell'azienda non può svolgere il proprio lavoro.

Inoltre, se stai costruendo un compilatore davvero complesso, non puoi semplicemente hackerarlo insieme. La logica alla base dei compilatori è sia altamente complessa che facile da formalizzare. Pertanto, questi programmi saranno spesso realizzati in modo molto "solido" e generico, il che tende a provocare meno bug.

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.