|
|
|
|
|
by jacquesm
5755 days ago
|
|
Even today, when you look at the core routines of for instance X windows C is still used in exactly that way, you don't have to but you definitely can and even though C compilers have advances tremendously the fact that there is a direct 1:1 correspondence between input and output is exactly why C is used in those situations. C supports multiple stacks if you tweak setjmp and longjmp just right, and using co-operative multi-threading is possible without any OS support. Not very useful if you really have to do two things at the same time but a lot nicer than interleaving a bunch of code. And an optimizing compiler is still a transformation of the input according to a given ruleset, you could not get the same level of optimization by just processing the output of the code generation stage of the compiler because you would lose a bunch of higher level information that is invaluable when optimizing the code but you could see it as just another stage in 'transforming' from one language to another without losing any functional bits along the way. |
|
Any half-decent compiler is going to perform a non-trivial transformation of a big switch statement to make it efficient. The expected performance semantics of a switch (something better than O(n) in the number of cases) rules out simplistic iterated jumps in big cases. The programmer expects O(1), or at worst, O(log n).
But more importantly, CPUs generally have many more capabilities than are exposed by C, and this is where the "1:1 correspondence" really falls down. Assemblers generally have disassemblers that you can transparently round-trip through. That's a little harder in C.
Perhaps you meant a injective relation, rather than bijective? But that's a long way short of an assembler.