From: Israel
Subject: Why compile to C or C++?
Date: 
Message-ID: <3b38bd14.85022085@news.lith.com>
This may be a boner question, but in my research into different
programming languages, I've found that many languages which claim to
be oh so much better than C and C++ often are compiled into C.

Am I missing something?  Why not have these languages like Lisp and
Dylan and so on just compile into machine code or something?

~Israel~   

From: Tim Bradshaw
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <nkj3d8np3yf.fsf@tfeb.org>
······@lith.com (Israel) writes:

> Am I missing something?  Why not have these languages like Lisp and
> Dylan and so on just compile into machine code or something?
> 

What Lisp compiles to depends on the implementation.  Native-compiled
implementations are at least as common as compile-to-C or
compile-to-bytecode ones at this point (and have probably always been).

The reason some implementations elect to compile to C is that it can
be used as a portable assembler: almost all systems have C compilers,
so if you target C you get portability (often with system-specific
tweaks).  It's Java compiling to JVM but probably better performance
and without the safety `guarantees'.

--tim
From: Israel
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <3b38c859.87907023@news.lith.com>
>tweaks).  It's Java compiling to JVM but probably better performance
>and without the safety `guarantees'.
>

Ah, so Python and Java requiring their own interpreters or virtual
macines is their way of ensuring portability and compiling to C is
other languages' way of crossing their fingers and hoping for the
same?

How would one deal with an implementation of Lisp that compiled
natively from Lisp to Machine ( i'm still fuzzy on the details), when
you had a program that you wanted to distribute to large nubers of
users?  Would you package your version of Lisp or an interpreter or
something along with the program?

~Israel~
From: Barry Margolin
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <s04_6.14$0v4.201@burlma1-snr2>
In article <·················@news.lith.com>, Israel <······@lith.com> wrote:
>How would one deal with an implementation of Lisp that compiled
>natively from Lisp to Machine ( i'm still fuzzy on the details), when
>you had a program that you wanted to distribute to large nubers of
>users?  Would you package your version of Lisp or an interpreter or
>something along with the program?

One option is to distribute source code.

If that's not acceptable, then you're limited to distributing to users who
are running a system that you have a compiler for, just as you would be if
you wrote the program in C.  Some Lisp implementations are able to produce
executables that have the Lisp runtime library incorporatd in them, so you
don't need to include anything extra with the application.  If not, you
might have to require that the users acquire a copy of the Lisp
implementation.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Tim Bradshaw
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <nkjsngmmel3.fsf@tfeb.org>
······@lith.com (Israel) writes:

> 
> Ah, so Python and Java requiring their own interpreters or virtual
> macines is their way of ensuring portability and compiling to C is
> other languages' way of crossing their fingers and hoping for the
> same?

Yes, precisely that.  To run Java you need an implementation of the
JVM which is likely written in C, but could be in any language,
including assembler or a native-compiled Java for instance), to run a
compile-to-C system you need a C compiler.

> 
> How would one deal with an implementation of Lisp that compiled
> natively from Lisp to Machine ( i'm still fuzzy on the details), when
> you had a program that you wanted to distribute to large nubers of
> users?  Would you package your version of Lisp or an interpreter or
> something along with the program?
> 

Well there are two things you need to support a program.  One is a
machine to run it on: if the system is compile-to-bytecode this means
you need the virtual machine that supports the system, such as JVM; if
it is compile-to-C or compile-to-native then you need the an
appropriate physical machine.  The other thing you need is the
`runtime system' to support the program: this is all the support code
that the program needs to run, usually defined as being everything
above the OS kernel.  This runtime system might already exist on the
target machine - this is usually the case for C/C++ systems, and
increasingly the case for Java systems too - or you may need to wrap
it up with the program, which is usually the case for Lisp systems
(this, incidentally, is why lisp applications are `big').

So if you want to distribute a Lisp (or other) program which is native
compiled, then you need to do two things: you need to provide suitable
compiled code for each platform you intend to target, and you need to
ensure that each platform has suitable runtime support.  Typically,
for Lisp - where you can't assume that the runtime support exists on
target machines - this is done by bundling up some kind of `runtime
version' of the Lisp system which contains the runtime support along
with your program.

This is all made slightly more complex by issues as to what defines a
`platform' - an x86 running Linux is not the same platform as one
runnign Windows, and this may alter not just the runtime support, but
the compiled code too, because there may be different calling
conventions and so on.  Even worse, an x86 running Windows may not be
a single platform, since there are significant differences between the
various Windows versions.

--tim
From: Simon Andr�s
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <vcd3d8ncfnz.fsf@russell.math.bme.hu>
······@lith.com (Israel) writes:

> This may be a boner question, but in my research into different
> programming languages, I've found that many languages which claim to
> be oh so much better than C and C++ often are compiled into C.

Portability might be a valid reason. (We're talking about
implementations, not languages, I guess.) But if the languages you
allude to (and I must admit I have no idea what these are) were
compiled to machine code, you probably would've said "many languages
which claim to be oh so much better than machine code often are
compiled into machine code". In other words, I don't understand your
sarcastic "claim to be oh so much better".

> 
> Am I missing something?  Why not have these languages like Lisp and
> Dylan and so on just compile into machine code or something?

I don't know about Dylan, but apart from GCL, no major Common Lisp
implementation compiles to C. At least Allegro CL, CMU CL, LispWorks
and MCL all compile to machine code.

Andras

> ~Israel~   
From: Barry Margolin
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <bV3_6.13$0v4.353@burlma1-snr2>
In article <···············@russell.math.bme.hu>,
Simon Andr�s <······@math.bme.hu> wrote:
>······@lith.com (Israel) writes:
>
>> This may be a boner question, but in my research into different
>> programming languages, I've found that many languages which claim to
>> be oh so much better than C and C++ often are compiled into C.
>
>Portability might be a valid reason. (We're talking about
>implementations, not languages, I guess.) But if the languages you

Portability is one reason, and ease of implementation may be another.
Writing code generators is lots of work, and writing code generators for
lots of different processors and operating systems is an order of magnitude
more work.  By using C as your back-end, you can leverage off all the work
that has already been done to write its code generators.  Since C is a
relatively low-level language, you don't lose much in the way of
performance by using it as an intermediary.

>allude to (and I must admit I have no idea what these are) were
>compiled to machine code, you probably would've said "many languages
>which claim to be oh so much better than machine code often are
>compiled into machine code". In other words, I don't understand your
>sarcastic "claim to be oh so much better".

He seems to be reasoning from a false premise: using C as the back-end will
cause the language to inherit C's faults.  Your analogy to machine code
shows the falacy of this logic.

Like assembler and machine code, C's faults are mainly in areas of
usability, not compilability.  Its simplicity and popularity have resulted
in some excellent compilers that produce very good code.  The problem with
C is that it's not as easy to write or read as higher-level languages like
Lisp.  By relegating C to the back-end, it gets used for what it's good at:
being a portable assembler.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Israel
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <3b38d1f6.90368092@news.lith.com>
Thanks, all.  

The whole compiler, linker, machine code hoohaw has had me rather
confused.  I come from an art background and as a result , my new
hobby lacks the essential computer science education that many of you
happen to have the benefit of.

Most of the Implementations of various languages I look at are the
free and/or open source ones.  This is mostly a result of my
programming being a hobby and as such it's hard to justify spending
big $ to just play around with stuff I hardly understand, but
miraculously can get to work.. on occasion.   So it's easy to
understand that a free implementation would not have the $ and time to
spend on porting their compiler to all the various platforms and
such..

~Israel~
From: Tim Bradshaw
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <nkju212mfm6.fsf@tfeb.org>
Barry Margolin <······@genuity.net> writes:

> 
> Like assembler and machine code, C's faults are mainly in areas of
> usability, not compilability.  Its simplicity and popularity have resulted
> in some excellent compilers that produce very good code.  The problem with
> C is that it's not as easy to write or read as higher-level languages like
> Lisp.  By relegating C to the back-end, it gets used for what it's good at:
> being a portable assembler.
> 

There's also the point that compile-to-C languages can produce C code
that no human could (easily) write and thus perhaps get performance
from the system that you would not easily be able to duplicate by
writing C.  The Stalin Scheme system compiles, I think, via C, and I
believe produces completely alien, and very high-performance, code.

--tim
From: Michael Hudson
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <m34rt22k1j.fsf@atrus.jesus.cam.ac.uk>
Barry Margolin <······@genuity.net> writes:

> He seems to be reasoning from a false premise: using C as the
> back-end will cause the language to inherit C's faults.  Your
> analogy to machine code shows the falacy of this logic.

Compiling to C (or writing an interpreter in C) seems to me to
restrict your choice of control-flow constructs severely.  Don't want
stack-based control flow?  Bad luck.

I guess this applies more to interpreters written in C than compiling
to C, but it's still a bit of a fight.

Cheers,
M.

-- 
  On the other hand, the following areas are subject to boycott
  in reaction to the rampant impurity of design or execution, as
  determined after a period of study, in no particular order:
    ...                              http://www.naggum.no/profile.html
From: Geoff Summerhayes
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <tjjtp0qev8ip72@corp.supernews.com>
"Michael Hudson" <···@python.net> wrote in message ···················@atrus.jesus.cam.ac.uk...
> Barry Margolin <······@genuity.net> writes:
>
> > He seems to be reasoning from a false premise: using C as the
> > back-end will cause the language to inherit C's faults.  Your
> > analogy to machine code shows the falacy of this logic.
>
> Compiling to C (or writing an interpreter in C) seems to me to
> restrict your choice of control-flow constructs severely.  Don't want
> stack-based control flow?  Bad luck.
>
> I guess this applies more to interpreters written in C than compiling
> to C, but it's still a bit of a fight.
>

Would you mind expanding on this? I'm not clear on what you are saying.
It strikes me that any language that has function calls that return
control to the callee is conceptually stack-based regardless of the
implementation.

Geoff
From: Barry Margolin
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <B0q_6.41$0v4.790@burlma1-snr2>
In article <··············@corp.supernews.com>,
Geoff Summerhayes <·············@hNoOtSmPaAiMl.com> wrote:
>
>"Michael Hudson" <···@python.net> wrote in message
>···················@atrus.jesus.cam.ac.uk...
>> Barry Margolin <······@genuity.net> writes:
>>
>> > He seems to be reasoning from a false premise: using C as the
>> > back-end will cause the language to inherit C's faults.  Your
>> > analogy to machine code shows the falacy of this logic.
>>
>> Compiling to C (or writing an interpreter in C) seems to me to
>> restrict your choice of control-flow constructs severely.  Don't want
>> stack-based control flow?  Bad luck.
>>
>> I guess this applies more to interpreters written in C than compiling
>> to C, but it's still a bit of a fight.
>>
>
>Would you mind expanding on this? I'm not clear on what you are saying.
>It strikes me that any language that has function calls that return
>control to the callee is conceptually stack-based regardless of the
>implementation.

That's what he's saying: most languages *only* have stack-based control
flow.  But if you want tail-call elimination or continuation-passing,
you're out of luck because C doesn't offer them.

However, the answer to this is that the Lisp compiler doesn't have to
translate Lisp control-flow constructs into the most obviously analogous C
construct.  I.e. a Lisp function call may not turn into a C function call.
The Lisp stack could be kept in a C array, and a function call would be
compiled into code that pushes arguments onto this array, followed by a
GOTO.

In fact, in order to implement lexical closures, you have to do things like
this, since ordinary C function arguments will be discard when the function
returns.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Geoff Summerhayes
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <tjkid27u1ana7c@corp.supernews.com>
"Barry Margolin" <······@genuity.net> wrote in message ·····················@burlma1-snr2...
> In article <··············@corp.supernews.com>,
> Geoff Summerhayes <·············@hNoOtSmPaAiMl.com> wrote:
> >
> >"Michael Hudson" <···@python.net> wrote in message
> >···················@atrus.jesus.cam.ac.uk...
> >> Barry Margolin <······@genuity.net> writes:
> >>
> >> > He seems to be reasoning from a false premise: using C as the
> >> > back-end will cause the language to inherit C's faults.  Your
> >> > analogy to machine code shows the falacy of this logic.
> >>
> >> Compiling to C (or writing an interpreter in C) seems to me to
> >> restrict your choice of control-flow constructs severely.  Don't want
> >> stack-based control flow?  Bad luck.
> >>
> >> I guess this applies more to interpreters written in C than compiling
> >> to C, but it's still a bit of a fight.
> >>
> >
> >Would you mind expanding on this? I'm not clear on what you are saying.
> >It strikes me that any language that has function calls that return
> >control to the callee is conceptually stack-based regardless of the
> >implementation.
>
> That's what he's saying: most languages *only* have stack-based control
> flow.  But if you want tail-call elimination or continuation-passing,
> you're out of luck because C doesn't offer them.
>
> However, the answer to this is that the Lisp compiler doesn't have to
> translate Lisp control-flow constructs into the most obviously analogous C
> construct.  I.e. a Lisp function call may not turn into a C function call.
> The Lisp stack could be kept in a C array, and a function call would be
> compiled into code that pushes arguments onto this array, followed by a
> GOTO.
>
> In fact, in order to implement lexical closures, you have to do things like
> this, since ordinary C function arguments will be discard when the function
> returns.
>

OK, I see it now, he's talking about the choices available in C itself
rather than the choices available from what the resultant spaghetti is
doing.
IIRC, the C specification doesn't prohibit tail-call elimination, it's
up to the people that write the compilers. I don't know if anyone has
bothered implement it though.

Geoff
From: Tim Bradshaw
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <nkj8zidbpmn.fsf@tfeb.org>
"Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> writes:

> IIRC, the C specification doesn't prohibit tail-call elimination, it's
> up to the people that write the compilers. I don't know if anyone has
> bothered implement it though.

gcc does it sometime.  There are weird restrictions imposed by C
semantics I think.

--tim
From: Ingvar Mattsson
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <87wv5n1wju.fsf@gruk.tech.ensign.ftech.net>
Tim Bradshaw <···@tfeb.org> writes:

> "Geoff Summerhayes" <·············@hNoOtSmPaAiMl.com> writes:
> 
> > IIRC, the C specification doesn't prohibit tail-call elimination, it's
> > up to the people that write the compilers. I don't know if anyone has
> > bothered implement it though.
> 
> gcc does it sometime.  There are weird restrictions imposed by C
> semantics I think.

More by C++ sematics on sequencing of automatic creation and
destruction, if you have auto-declared objects. At least that's what I
recall of a discussion on tail-call elimination years and years ago.

//Ingvar
-- 
"Madwolf opening conversational salvo will notice that's interesting."
	Pfy
From: Daniel E. Wilson
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <3B3B67B8.6030207@teleport.com>
Geoff Summerhayes wrote


> OK, I see it now, he's talking about the choices available in C itself
> rather than the choices available from what the resultant spaghetti is
> doing.
> IIRC, the C specification doesn't prohibit tail-call elimination, it's
> up to the people that write the compilers. I don't know if anyone has
> bothered implement it though.

I believe that GCC 3.0 will have that optimization.  Very few C 
compilers have ever had tail-call elimination.  Recursion something
be avoided in C and C++ because of function call overhead.  Something
about C and C++ makes programmers optimize the code before they get
the program working.  I tend to C and C++ only when I can't avoid it.
From: Tim Bradshaw
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <nkjhex0ebix.fsf@tfeb.org>
"Daniel E. Wilson" <·······@teleport.com> writes:

> 
> I believe that GCC 3.0 will have that optimization.  Very few C 
> compilers have ever had tail-call elimination.  Recursion something
> be avoided in C and C++ because of function call overhead.  Something
> about C and C++ makes programmers optimize the code before they get
> the program working.  I tend to C and C++ only when I can't avoid it.

GCC already has this optimisation in some cases - I think self-calls.
There are some subtelties with C calling conventions which make
general tail-call elimination hard for C I think.  I *think* the
problem is this:

C generally does function call by caller-pop (I'm not sure if this is
the correct term): if A is calling B, it pushes arguments onto the
stack, calls B, and then pops them (this is in the case that you can't
get all the args into registers &c).  So the interesting case to
consider is this:

A calls B with n args, B tail-calls C with m args, and m > n.  If the
compiler does tail-call elimination, then when B returns, there are m
args on the stack.  But A only pushed n, and will therefore only pop
n, and since m > n you lose.

Of course this doesn't make it always impossible, it just means that
there are restrictions.  There are other cases like this:

    void grib(int *pi);
    int grub(void), fob(void);
    int *stash;

    int fob()
    {
      int i = 1;
      grib(&i);
      return (grub());
    }

    void grib(int *pi)
    { 
      stash = pi;
    }

    int grub()
    {
      return (*stash);
    }

The call to grub is a tail call, but doing tail-call elimination will
cause the i local to fob to get lost, and since it has been secretly
stashed by grib you lose.

So I think it's quite hard to do things in the general case.


--tim

[PLEASE DON'T FLAME ME for bad C: if these examples are wrong or
illegal I am more than happy to be corrected, told I am wrong or
whatever: I'm no C expert, these examples come from a distantly
remembered discussion with someone who was, and I could easily be
misremembering.]


 
From: Daniel E. Wilson
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <3B3C3023.1050508@teleport.com>
Tim Bradshaw wrote:

> "Daniel E. Wilson" <·······@teleport.com> writes:
> 
> 
>>I believe that GCC 3.0 will have that optimization.  Very few C 
>>compilers have ever had tail-call elimination.  Recursion something
>>be avoided in C and C++ because of function call overhead.  Something
>>about C and C++ makes programmers optimize the code before they get
>>the program working.  I tend to C and C++ only when I can't avoid it.
>>
> 
> GCC already has this optimisation in some cases - I think self-calls.
> There are some subtelties with C calling conventions which make
> general tail-call elimination hard for C I think.  I *think* the
> problem is this:
> 
> C generally does function call by caller-pop (I'm not sure if this is
> the correct term): if A is calling B, it pushes arguments onto the
> stack, calls B, and then pops them (this is in the case that you can't
> get all the args into registers &c).  So the interesting case to
> consider is this:
> 
> A calls B with n args, B tail-calls C with m args, and m > n.  If the
> compiler does tail-call elimination, then when B returns, there are m
> args on the stack.  But A only pushed n, and will therefore only pop
> n, and since m > n you lose.
> 
> Of course this doesn't make it always impossible, it just means that
> there are restrictions.  There are other cases like this:
> 
>     void grib(int *pi);
>     int grub(void), fob(void);
>     int *stash;
> 
>     int fob()
>     {
>       int i = 1;
>       grib(&i);
>       return (grub());
>     }
> 
>     void grib(int *pi)
>     { 
>       stash = pi;
>     }
> 
>     int grub()
>     {
>       return (*stash);
>     }
> 
> The call to grub is a tail call, but doing tail-call elimination will
> cause the i local to fob to get lost, and since it has been secretly
> stashed by grib you lose.
> 
> So I think it's quite hard to do things in the general case.


It's the argument passing convention that trips C class languages up.
Arguments are placed and removed from the stack by the caller.  In the
K&R version of the language there were no function prototypes.  This 
meant that only the function caller would know what was passed to the
function.  Its not hard to see the complications this would make for
getting the stack frames right in your example.

Even after function prototypes were adopted for ANSI C from C++ the same
problem still exists.  In order to support a variable length argument 
list you have to specify '...' to turn off the type checking for the
remaining arguments.  You don't even want to know what the function
itself has to do in order to access the arguments.

When I program in C and C++ my first cut of a program may use recursion
until I get it working.  Then I start converting recursive control 
structures to iterative ones.  This buys me less stack usage and a 
faster program.  In system and embedded programming stack tends to
be limited.

I use Python and LISP and save C and C++ for when I can't do it any 
other way.  Which amounts to someone making it a project requirement.
The Portland State Computer Science program is based mostly in C++
which I regard as a really bad choice of a first programming language.
From: Lieven Marchand
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <m3vglf8bjk.fsf@localhost.localdomain>
"Daniel E. Wilson" <·······@teleport.com> writes:

> It's the argument passing convention that trips C class languages up.
> Arguments are placed and removed from the stack by the caller.  In the
> K&R version of the language there were no function prototypes.  This 
> meant that only the function caller would know what was passed to the
> function.  Its not hard to see the complications this would make for
> getting the stack frames right in your example.
> 
> Even after function prototypes were adopted for ANSI C from C++ the same
> problem still exists.  In order to support a variable length argument 
> list you have to specify '...' to turn off the type checking for the
> remaining arguments.  You don't even want to know what the function
> itself has to do in order to access the arguments.

The ISO C standard doesn't determine any argument passing convention
or even the existence of a stack. One C implementation I've worked
with on an IBM mainframe operating system used linked list of
activation records in stead of a stack. This worked better with the
operating systems convention and the machine didn't have stack
instructions in hardware anyway. I don't remember whether it was done
that way but there was enough information in the activation record to
allow the callee to remove the record.

-- 
Lieven Marchand <···@wyrd.be>
You can drag any rat out of the sewer and teach it to get some work done in
Perl, but you cannot teach it serious programming.              Erik Naggum
From: Daniel E. Wilson
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <3B3D8C31.9070708@teleport.com>
Lieven Marchand wrote:

> "Daniel E. Wilson" <·······@teleport.com> writes:
> 
> 
>>It's the argument passing convention that trips C class languages up.
>>Arguments are placed and removed from the stack by the caller.  In the
>>K&R version of the language there were no function prototypes.  This 
>>meant that only the function caller would know what was passed to the
>>function.  Its not hard to see the complications this would make for
>>getting the stack frames right in your example.
>>
>>Even after function prototypes were adopted for ANSI C from C++ the same
>>problem still exists.  In order to support a variable length argument 
>>list you have to specify '...' to turn off the type checking for the
>>remaining arguments.  You don't even want to know what the function
>>itself has to do in order to access the arguments.
>>
> 
> The ISO C standard doesn't determine any argument passing convention
> or even the existence of a stack. One C implementation I've worked
> with on an IBM mainframe operating system used linked list of
> activation records in stead of a stack. This worked better with the
> operating systems convention and the machine didn't have stack
> instructions in hardware anyway. I don't remember whether it was done
> that way but there was enough information in the activation record to
> allow the callee to remove the record.

That may be true but even in this implementation you are simulating a stack

and the activation records have to be allocated and deallocated from the
heap.  I will bet that the caller still has to handle this for the same
reason as the stack implementation.

It still seems like the same complications are still present in handling
activation record.




-- 
Daniel E. Wilson <·······@teleport.com>

If you don't have freedom as a principle, you can never
see a reason not to make an exception.
         - Richard M. Stallman
From: Casper H.S. Dik - Network Security Engineer
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <9i1jrl$mmo$1@new-usenet.uk.sun.com>
[[ PLEASE DON'T SEND ME EMAIL COPIES OF POSTINGS ]]

Tim Bradshaw <···@tfeb.org> writes:

>GCC already has this optimisation in some cases - I think self-calls.

Sun's SPARC compilers also do tail call elimination.

>There are some subtelties with C calling conventions which make
>general tail-call elimination hard for C I think.  I *think* the
>problem is this:

>C generally does function call by caller-pop (I'm not sure if this is
>the correct term): if A is calling B, it pushes arguments onto the
>stack, calls B, and then pops them (this is in the case that you can't
>get all the args into registers &c).  So the interesting case to
>consider is this:


>A calls B with n args, B tail-calls C with m args, and m > n.  If the
>compiler does tail-call elimination, then when B returns, there are m
>args on the stack.  But A only pushed n, and will therefore only pop
>n, and since m > n you lose.

That's not a problem with the SPARC calling convention; arguments
are passed in registers (excess on the stack) and the called
function links the next frame and pops it if need be.

The example code has grib and grub inlined; with fob in a separate
file, the fact that "&i" is possible visible defeats tail call elimiation;
if the compiler can prove that "i" isn't visible, the tail call
is eliminated:

		mv %o7,%g1
		call grub
		mv %g1,%o7


(the call function puts "pc" in %o7; the instruction after call
is executed also and the complete code sequence simply saves the return
address and restores it)

If the "grub" address is known to be close it would have been just:

		ba grub
		nop


In the case that squirrels away &i, the compiler does create
a stack frame to retain "i".

Register windows make tail call elimination more of a necessarity;
but because it's the called function that is in charge of creating
a new stack frame, no adjusting is necessary and the code generation
is a simple question of whether there are variables visible on the
stack during the call and whether the calling function returns void or
the value returned by the tail-call.

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
From: Michael Hudson
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <m3sngl20sp.fsf@atrus.jesus.cam.ac.uk>
Barry Margolin <······@genuity.net> writes:

> In article <··············@corp.supernews.com>,
> Geoff Summerhayes <·············@hNoOtSmPaAiMl.com> wrote:
> >
> >"Michael Hudson" <···@python.net> wrote in message
> >···················@atrus.jesus.cam.ac.uk...
> >> Barry Margolin <······@genuity.net> writes:
> >>
> >> > He seems to be reasoning from a false premise: using C as the
> >> > back-end will cause the language to inherit C's faults.  Your
> >> > analogy to machine code shows the falacy of this logic.
> >>
> >> Compiling to C (or writing an interpreter in C) seems to me to
> >> restrict your choice of control-flow constructs severely.  Don't want
> >> stack-based control flow?  Bad luck.
> >>
> >> I guess this applies more to interpreters written in C than compiling
> >> to C, but it's still a bit of a fight.
> >>
> >
> >Would you mind expanding on this? I'm not clear on what you are saying.
> >It strikes me that any language that has function calls that return
> >control to the callee is conceptually stack-based regardless of the
> >implementation.
> 
> That's what he's saying: most languages *only* have stack-based control
> flow.  But if you want tail-call elimination or continuation-passing,
> you're out of luck because C doesn't offer them.

Yes, that's what I meant.  Thanks for explaining for me :-)

> However, the answer to this is that the Lisp compiler doesn't have to
> translate Lisp control-flow constructs into the most obviously analogous C
> construct.  I.e. a Lisp function call may not turn into a C function call.
> The Lisp stack could be kept in a C array, and a function call would be
> compiled into code that pushes arguments onto this array, followed by a
> GOTO.

Yes again; this is what inspired the partial retraction about this
affecting interpreters written in C more than compiling to C (at least
if you want your interpreter to be written in relatively idiomatic and
portable C).

Cheers,
M.

-- 
  Famous remarks are very seldom quoted correctly.
                                                    -- Simeon Strunsky
From: David Douthitt
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <3B3B1F88.E278E52D@mailbag.com>
······@lith.com (Israel) writes:

> This may be a boner question, but in my research into different
> programming languages, I've found that many languages which claim to
> be oh so much better than C and C++ often are compiled into C.

I don't think it is a "boner question", and I've been a rabid student of
many computer languages over the last 20+ years.

"Simon Andr�s" wrote:
>
> Portability might be a valid reason.

Makes good sense.

> But if the languages you
> allude to (and I must admit I have no idea what these are) [...]

There are many.  SmallEiffel comes to mind; Embeddable Common Lisp Spain
(ECLS) is another; Sather and Linda are yet two more.  Seems to me there
were many more.

> [...] were
> compiled to machine code, you probably would've said "many languages
> which claim to be oh so much better than machine code often are
> compiled into machine code". In other words, I don't understand your
> sarcastic "claim to be oh so much better".

I do.  Why write in another language instead of C when one can write in
C to begin with?  Why write a program in LISP if it's only going to be
converted to C?  One can skip all that and write directly to C - and
perhaps optimize the code better and skip an extra compile step.

> > Am I missing something?  Why not have these languages like Lisp and
> > Dylan and so on just compile into machine code or something?

This, in my mind, is a good question; others have answered ably, calling
C a "portable assembler."

Another question: doesn't the reliance of these languages (ECLS, Sather,
SmallEiffel, Linda....) on a C back-end make them susceptible to stack
smashing, buffer overflow, and print format string attacks?
From: Tim Bradshaw
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <nkjpubog2no.fsf@tfeb.org>
David Douthitt <·····@mailbag.com> writes:

> I do.  Why write in another language instead of C when one can write in
> C to begin with?  Why write a program in LISP if it's only going to be
> converted to C?  One can skip all that and write directly to C - and
> perhaps optimize the code better and skip an extra compile step.
> 

I think you should look at the code generated by some of the serious
x-to-C compilers.  Yes, you could write it yourself, in the sense that
you could type those characters in, but whether you could understand
what it did or maintain it, or in fact think it up in the first place,
is another question.

--tim
From: Barry Margolin
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <cdI_6.9$_F5.237@burlma1-snr2>
In article <·················@mailbag.com>,
David Douthitt  <·····@callsign.net> wrote:
>Another question: doesn't the reliance of these languages (ECLS, Sather,
>SmallEiffel, Linda....) on a C back-end make them susceptible to stack
>smashing, buffer overflow, and print format string attacks?

Not usually.  Those attacks are possible because someone writing in C might
leave out things like array bounds checks, and the attacker exploits these
bugs in the application.  But a Lisp compiler will generate code that
performs the checks.

Actually, I suppose in low SAFETY and high SPEED optimization settings, the
Lisp compiler could leave out those checks, and you could then be
susceptible to these exploits.  But the same is true for compilers that
generate native code directly.  If the implementation doesn't do bounds
checks, and the application doesn't check, you're open to such attacks.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Kent M Pitman
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <sfwithgtx3l.fsf@world.std.com>
Barry Margolin <······@genuity.net> writes:

> 
> In article <·················@mailbag.com>,
> David Douthitt  <·····@callsign.net> wrote:
> >Another question: doesn't the reliance of these languages (ECLS, Sather,
> >SmallEiffel, Linda....) on a C back-end make them susceptible to stack
> >smashing, buffer overflow, and print format string attacks?
> 
> Not usually.  Those attacks are possible because someone writing in C might
> leave out things like array bounds checks, and the attacker exploits these
> bugs in the application.  But a Lisp compiler will generate code that
> performs the checks.
> 
> Actually, I suppose in low SAFETY and high SPEED optimization settings, the
> Lisp compiler could leave out those checks, and you could then be
> susceptible to these exploits.  But the same is true for compilers that
> generate native code directly.  If the implementation doesn't do bounds
> checks, and the application doesn't check, you're open to such attacks.

I remember a conversation a very long time ago with Steve Gadol at a
conference (probably AAAI), who I think was at Sun at the time, about
the Sun SPE for Common Lisp, which purported to be very like the Lisp
Machine.  He explained to me he'd looked at the generated code over
and over and it just seemed to him that there was no material
difference between the Sun environment (which generated all
appropriate type checks, he said) and the Genera environment's
hardware-level isntruction stream, and asked me why it was that people
still liked Lisp Machines and weren't just jumping ship for the Sun
environment.  I told him the one thing that was still different was
that an overzealous manager could still ask that code be compiled at
low-safety and high speed, squeezing extra speed out of the Sun
environment, but at loss of safety.  For myself, I said, I like the
protection against such foolishness.  The physical impossibility on
the LispM of someone to make this tradeoff was reassuring to me...
I may be unique in this point of view.  I've always elected, where I
could, to run my programs slower with runtime error checks.  The Maclisp
compiler used to have an option that would do this, and I don't know many
who used it other than me... What can I say?  Soem paranoia runs deep.
From: Bob Bane
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <3B3B670A.4E6ACE80@removeme.gst.com>
I forget who said this in response to a question about how all that
type-checking, bounds-checking, error-detecting, etc., code slowed
programs down:

	"How fast do you want the wrong answer?"

-- 
Remove obvious stuff to e-mail me.
Bob Bane
From: Kurt B. Kaiser
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <m3ithgilar.fsf@float.ne.mediaone.com>
David Douthitt <·····@mailbag.com> writes:
 
> Another question: doesn't the reliance of these languages (ECLS, Sather,
> SmallEiffel, Linda....) on a C back-end make them susceptible to stack
> smashing, buffer overflow, and print format string attacks?

Well, those things are possible in machine code, also =).  Isn't it up to the
translation to C (with associated checks) to catch them?

Isn't the issue more that in going through C you have one layer of optimization
from source language to C, and another layer of optimization going from C to
machine?  These two layers may be less efficient than optimizing the overall
source to machine translation.  Also, you may be limited by some inexpressivity
in C.

Regards, KBK
From: Barry Margolin
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <NWM_6.27$_F5.434@burlma1-snr2>
In article <··············@float.ne.mediaone.com>,
Kurt B. Kaiser <···@shore.net> wrote:
>Isn't the issue more that in going through C you have one layer of optimization
>from source language to C, and another layer of optimization going from C to
>machine?  These two layers may be less efficient than optimizing the overall
>source to machine translation.  

You could say the same thing about macros.  When you use LOOP, you have one
layer of optimization translating from LOOP to LET/BLOCK/TAGBODY, and
another layer going from there to whatever the compiler generates.  But I
don't think you'll find many compiler authors putting in a special code
generator for LOOP in order to avoid this.

>				 Also, you may be limited by some inexpressivity
>in C.

This could be true.  But one of C's benefits is that it's a pretty
low-level language.  It was designed so that there would be obvious
correspondences between C operators and native machine operations.  Things
that "look quick" because they're a built-in operator rather than a
function call generally are about as efficient as possible -- there isn't
much magic going on behind the scenes when programming in C.

For application programmers this is a misfeature, since it means that they
have to write more code because the language provides so little.  But for
compiler writers using C as the back-end, it's great.  There's not too much
that isn't expressible in C, although some things may not be expressed in
the most obvious way, or the way that you would express them if you were
coding the application directly in C.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Basile STARYNKEVITCH
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <q5rae2vq9r0.fsf@amadeus.lesours>
>>>>> "Israel" == Israel  <······@lith.com> writes:

    Israel> This may be a boner question, but in my research into
    Israel> different programming languages, I've found that many
    Israel> languages which claim to be oh so much better than C and
    Israel> C++ often are compiled into C.

As several people mentioned, C can be used as a portable assembler.

An interesting project is C--. It is a language explicitly designed to
be a target langage for compilers. (It is low level, but offers better
support for garbage collection and full support of tail
recursion). See http://www.cminusminus.org/ for details
-- 

Basile STARYNKEVITCH -- http://perso.wanadoo.fr/starynkevitch/basile/
email: basile dot starynkevitch at wanadoo dot fr (France)
alias: basile at tunes dot org       host: http://lesours.dyndns.org/
8, rue de la Fa�encerie, 92340 Bourg La Reine, phone: +33 1.4665.4553
From: Thomas F. Burdick
Subject: Re: Why compile to C or C++?
Date: 
Message-ID: <xcvy9qdvisp.fsf@apocalypse.OCF.Berkeley.EDU>
Basile STARYNKEVITCH <·······················@SPAM.wanadoo.fr> writes:

> >>>>> "Israel" == Israel  <······@lith.com> writes:
> 
>     Israel> This may be a boner question, but in my research into
>     Israel> different programming languages, I've found that many
>     Israel> languages which claim to be oh so much better than C and
>     Israel> C++ often are compiled into C.
> 
> As several people mentioned, C can be used as a portable assembler.
> 
> An interesting project is C--. It is a language explicitly designed to
> be a target langage for compilers. (It is low level, but offers better
> support for garbage collection and full support of tail
> recursion). See http://www.cminusminus.org/ for details

After an admittedly quick glance at this project, I don't really see
why I would want to use it over gcc.  The benefits it touts over C
don't seem to apply to GNU C as implemented in GCC 3.0.