2013-08-13 18 views
5

Sono rimasto incuriosito quando ho sentito che GHC può inviare un file a C.Impossibile emettere da .hs a .hc con GHC in Haskell

Il Glasgow Haskell Compiler (GHC) compila codice nativo su un certo numero di architetture diverse, nonché su ANSI C-using C-- come lingua intermedia.

Così ho installato la piattaforma Haskell e creato un semplice file .hs.

main = putStrLn "Hello, World!" 

E secondo il manuale.

-C arresto dopo la generazione C (file .hc)

Ora eseguire il comando.

ghc -C test.hs 

Ma non crea un file .hc e non interrompe la compilazione a metà.

$ ls 
test.exe test.hi test.hs test.o 
+2

Hai provato a passare -fvia-C in aggiunta a -C? IIRC GHC non usa il backend C di default (può generare direttamente assembly per varie macchine, incluso llvm). – Cubic

+0

Ho ricevuto un avvertimento dicendo che "Il flag -fvia-C non fa nulla, sarà rimosso in una futura versione di GHC". Augustss, perché dovrei essere deluso? –

+2

Sembra completamente diverso dal codice C scritto da un essere umano. È fondamentalmente illeggibile. Inoltre, non è così efficiente come speri. L'unico modo in cui diventa efficiente è il mangling del codice assembly generato dal compilatore C. – augustss

risposta

7

Se si vuole capire come i programmi Haskell eseguono a un livello basso, è probabilmente meglio per studiare core invece (-ddump-simpl). Dopo quel punto il codice diventa davvero difficile da leggere anche per gli esperti. La ragione principale è che lo stack e la gestione dell'heap di GHC diventano hard-coded. Di conseguenza, il codice Haskell di basso livello generato è fondamentalmente un gigantesco pasticcio di minuscole procedure, facendo aritmetica puntatore complessa prima di finire con salti indiretti in posizioni sconosciute. Il peggior tipo di codice spaghetti.

di fornire qualcosa di una risposta reale - si potrebbe generare C andando oltre il backend LLVM:

ghc -ddump-llvm -ddump-to-file hello_world.hs 
opt -O2 hello_world.dump-llvm | llc -O2 -march c -o hello_world.c 

Ma il risultato sarà solo illustrare il punto. Anche una banale funzione fib richiede circa 80 righe di codice.

Nel caso in cui sei veramente interessato ai dettagli cruenti, ti consiglio di leggere lo this blog post di Edward Z. Yang. Praticamente cammina attraverso l'intera pipeline di compilazione coinvolta nella traduzione di un semplice pezzo di codice Haskell.

+0

Impressionante, ottenuto in C++. Trasforma a ciò apparentemente: D http://pastebin.com/r4Dy0ZD5 –

+0

Che genera tonnellate di errori in Clang e GCC: P –

+0

Si noti che il codice C++ incollato è in realtà un * generatore * per il codice macchina finale (usando LLVM come libreria). Ma cercare di gestirlo è in ogni caso futile, fidati ... –

Problemi correlati