Invece di compilare in assembly, facciamo un approccio più pratico (che esiste).
Ci sono programmi come f2c e p2c che compila fortran e pascal in c. La domanda è quindi "questi compilatori possono scrivere un codice migliore di quello che puoi?" In p2c (ad esempio), è necessario scrivere codice aggiuntivo in C per gestire l'elaborazione della stringa.
Questo si traduce anche nel montaggio. Ogni volta che c'è qualcosa che il linguaggio sta facendo per te, sotto le coperte, c'è il probabile cappuccio che un programmatore con la comprensione delle strutture e degli algoritmi necessari per scrivere scriverebbe un codice più compatto (e più veloce) in C.
(edit)
Consideriamo un linguaggio tipizzato dinamico con stringhe e int, un operatore "+" completamente sovraccarico e un comando di stampa.
var foo = 3;
var bar = "a";
var qux = bar + foo;
print qux;
La versione C di questo programma sarebbe:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
int foo = 3;
char *bar = "a";
char qux[3];
sprintf(qux,"%s%d",bar,foo);
printf("%s",qux);
}
(Sì, so che non è ottimale ed è un esempio forzato) Che compila il seguente assembly sulla mia macchina (gcc -S -O9 foo.c)
.file "foo.c"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "a"
.LC1:
.string "%s%d"
.LC2:
.string "%s"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB23:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
movl $3, %ecx
movl $.LC0, %edx
movl $.LC1, %esi
xorl %eax, %eax
subq $16, %rsp
.cfi_def_cfa_offset 32
movq %rsp, %rdi
.cfi_offset 3, -16
call sprintf
movq %rsp, %rsi
movl $.LC2, %edi
xorl %eax, %eax
call printf
addq $16, %rsp
.cfi_def_cfa_offset 16
popq %rbx
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE23:
.size main, .-main
.ident "GCC: (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.string "Ospwg"
.section .note.GNU-stack,"",@progbits
A questo punto, la domanda è: cosa ci vorrebbe per scrivere un compilatore che sarebbe in grado di analizzare il codice dinamico e generare quell'assemblaggio. Mentre potrebbe essere possibile con quel linguaggio estremamente limitato, una volta che si inizia ad aggiungere più complessità al linguaggio, una traduzione in qualcosa più vicino alla macchina richiede sempre più codice per gestire la tipizzazione dinamica o il proprio runtime (l'obiettivo C prende questo approccio ) - in entrambi i casi, sarà più lento di qualcosa scritto in C che non ha bisogno di avere quell'overhead.
Oppure, il compilatore ha analizzato tutti i percorsi di esecuzione del codice (per il linguaggio dinamico) che credo equivalga a risolvere il problema dell'arresto.