From: | "Bartc" <bc@freeuk.com> |
Newsgroups: | comp.compilers |
Date: | Sun, 23 Jan 2011 20:09:44 -0000 |
Organization: | A noiseless patient Spider |
References: | 11-01-082 11-01-088 11-01-092 11-01-103 |
Keywords: | code, C |
Posted-Date: | 23 Jan 2011 21:38:10 EST |
"Tony" <nospam@myisp.net> wrote
>> Steven Shaw wrote:
>
>> [C can be a perfectly reasonable intermediate language so long as you
>> don't expect the C code to be readable by humans or to look anything
>> like the source code. -John]
>
> The key word being the very subjective "reasonable"? If one wanted a
> replacement language for C, but with a completely different type
> system, would C be a "reasonable" IL? It seems undoable for efficiency
> reasons. I'm not sure how one would go about implementing a
> language's type system in C and still get high performance. That is,
> performance equivalent to C.
> [C's type system is intended to be pretty close to what the hardware
> provides. You want a different type system, you can encode it using
> C's types. Think if it as a sort of high level assembler. -John]
I've attempted targetting C a few times and always gave up.
C has it's own idiosyncracies which get in the way (other than the
problem of accurately generating the syntax of another language;
readability while not essential is still important).
You say C's type system is close to the hardware, but just try and declare a
type of exactly 32-bits! It might be int or long int. On some C's it might
be int32_t, or is it int_least32_t, or int_fast32_t?
Then even with a source language close to C, but with minor differences,
there are problems:
int a
real b
equivalence(a,b)
Here, a (32 bits) and b (64 bits) occupy the same location in memory. How to
achieve this in C? Up to recently I might do something like:
double b;
*(int*)&b // replace all 'a' by this expression.
Now I find this in general is not guaranteed to work in C, especially in
optimised code, because pointers to ints and pointers to doubles are
assumed never to point to the same place.
This trick could have dispensed with many C features which would be
troublesome to map to a different language, now it cannot be used.
Or, you might want to use a calling convention unknown to C. Or unusual ways
of linking modules.
Just the use of identifiers is a big enough headache: C has its own
set, yours may use some unusual ways of creating identifiers: not case
sensitive, embedded spaces, namespaces, whatever. These fortunately
can be got around, but it's all a lot of extra work.
And then you find it will only work on a specific compiler with
particular options, creating a dependency. So much for
portability... And performance now depends on factors not directly
under your control.
Then if you want to debug the result, it will be in terms of the alien C
code which the user of your language wasn't even aware of, complete with
scrambled identifiers!
I'm not saying it's impossible to target C, but it can be more trouble than
it's worth, with 700 pages of the C Standard to consider between your
language, and the hardware you want to target.
--
Bartc
[I think this all falls under the category of not expecting the target
code to look like the source code. I agree the debugging isn't going
to be great unless you build in your own debugging stuff which has
exciting problems of its own. -John]
Return to the
comp.compilers page.
Search the
comp.compilers archives again.