[comp.lang.c++] C++ --> C

jordan@cs.columbia.edu (Jordan Hayes) (04/13/89)

Say you don't have a C++ compiler for a certain kind of machine,
but you do have a C compiler.

Say you've got a Sun somewhere on the same network.

Can you get g++ or cfront to generate C on the Sun and have the
unnamed machine compile that?

/jordan

ark@alice.UUCP (Andrew Koenig) (04/14/89)

In article <173@cs.columbia.edu>, jordan@cs.columbia.edu (Jordan Hayes) writes:

> Say you don't have a C++ compiler for a certain kind of machine,
> but you do have a C compiler.

> Can you get g++ or cfront to generate C on the Sun and have the
> unnamed machine compile that?

I can't speak for g++, but cfront will do that just fine.

In fact all it does is generate C -- and there are ways to talk it
into generating C for a machine that differs from the one it's
running on.  I think it's the +x option.
-- 
				--Andrew Koenig
				  ark@europa.att.com

newsuser@LTH.Se (LTH network news server) (04/14/89)

In article <173@cs.columbia.edu> jordan@cs.columbia.edu (Jordan Hayes) writes:
>Say you don't have a C++ compiler for a certain kind of machine,
>but you do have a C compiler.
>
>Say you've got a Sun somewhere on the same network.
>
>Can you get g++ or cfront to generate C on the Sun and have the
>unnamed machine compile that?

I think you would be heading for a lot of work:

   1.	There are some machine dependent parts in your compiler,
	e.g., sizes of basic data types, alignment, etc.

   2.	The C code will have all macros and inline functions expanded.
	As many machine dependent issues are described by macros in
	the system header files, you must make sure the C++ compiler
	on the development machine uses the header files of the target
	machine.

   3.	Debugging the C code produced by the C++ compiler is not funny.
	Can you be sure you got it right?  I am more willing to trust
	a ported compiler than a ported application.

   4.	Every change in the original C++ program (or even worse, a new
	release of system software on your target machine), requires you
	to port the application again. (It will of course be easier
	the n:th time.)

My view is that the C code produced by a C++ compiler is not particularly
portable, but I'm sure it can be, and has been, done.

Assuming the target machine is "similar" to your Sun, I would try porting
the compiler.  I think that is more cost-effective in the long run.

Dag Bruck
-- 
Department of Automatic Control		Internet:  dag@control.lth.se
Lund Institute of Technology
P. O. Box 118				Phone:	+46 46-108779
S-221 00 Lund, SWEDEN			Fax:    +46 46-138118

jwolf@hpcupt1.HP.COM (John Wolf) (04/14/89)

Sun's g++ is a true compiler, not a translater (i.e. produces object code
not C source code) - I think.  But find an AT&T C++ compiler (really a 
translator) and you maybe in business.

leech@zeta.cs.unc.edu (Jonathan Leech) (04/15/89)

In article <1989Apr14.082659.19048@LTH.Se> dag@Control.LTH.Se (Dag Bruck) writes:
>>Can you get g++ or cfront to generate C on the Sun and have the
>>unnamed machine compile that?
>My view is that the C code produced by a C++ compiler is not particularly
>portable, but I'm sure it can be, and has been, done.

    Since the way you port cfront is to cross-compile it for the
new machine, it certainly can be, and has been (many times), done.

>Assuming the target machine is "similar" to your Sun, I would try porting
>the compiler.

    Similarity is irrelevant, as long as it runs a reasonably standard
Unix. I even managed to port cfront from a Sun-3 to a DG MV/10000,
which has a painfully dissimilar architecture to almost everything
(word-addressed, stack grows up, non-standard object file format, no
'nm' for munch, etc.)

>I think that is more cost-effective in the long run.

    No argument there.
--
    Jon Leech (leech@cs.unc.edu)    __@/
    ``Are there any more questions, besides the ones from the
      liberal communists?''
	- George Uribe, natl. director of "Students For America"

rfg@riunite.ACA.MCC.COM (Ron Guilmette) (04/16/89)

Sorry, but I just can't let this go by.

In article <7050005@hpcupt1.HP.COM> jwolf@hpcupt1.HP.COM (John Wolf) writes:
>Sun's g++ is a true compiler, not a translater (i.e. produces object code
>not C source code) - I think.

Mr. Wolf's facts are as erroneous as his spelling (e.g. translater).

In case anyone reading this newsgroup doesn't know already, the GNU G++
compiler *does not*, in any way shape or form, belong to Sun.  The GNU G++
compiler was developed here at the Microelectronics and Computer Technology
Corporation (an industry consortium) in Austin, Texas, by Michael Tiemann
(now attending Stanford University).  This compiler was based primarily on
existing code for an ANSI C compiler, developed by Richard Stallman of the
Free Software Foundation, Cambridge, Massachusetts.  Very early in its life,
the code for the G++ compiler was donated to the Free Software Foundation by
MCC and Michael Tiemann.  This code in now the property of FSF and is covered
by FSF copyleft provisions, which make it freely available to the public under
certain conditions and with certain restrictions.

As far as I know, Sun has no ownership interests in the GNU G++ compiler.

-- 
// Ron Guilmette  -  MCC  -  Experimental Systems Kit Project
// 3500 West Balcones Center Drive,  Austin, TX  78759  -  (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg

ark@alice.UUCP (Andrew Koenig) (04/16/89)

In article <7050005@hpcupt1.HP.COM>, jwolf@hpcupt1.HP.COM (John Wolf) writes:
> Sun's g++ is a true compiler, not a translater (i.e. produces object code
> not C source code) - I think.  But find an AT&T C++ compiler (really a 
> translator) and you maybe in business.

Why do pepole say that a compiler that produces C as its
object code isn't a `true compiler' but a compiler that
produces assembly language is?  Do you think it's significantly
easier to translate C++ into C than into assembly language?

[answer: it isn't -- but it certainly is easier to translate
C++ into C that will run on a dozen different machines than it
is to translate C++ into a dozen different assembly languages!]
-- 
				--Andrew Koenig
				  ark@europa.att.com

bart@videovax.tv.Tek.com (Bart Massey) (04/17/89)

In article <9204@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes:
> 
> Why do pepole say that a compiler that produces C as its
> object code isn't a `true compiler' but a compiler that
> produces assembly language is?  Do you think it's significantly
> easier to translate C++ into C than into assembly language?
> 
> [answer: it isn't -- but it certainly is easier to translate
> C++ into C that will run on a dozen different machines than it
> is to translate C++ into a dozen different assembly languages!]

Conjecture:  Perhaps because they have ATT cfront as their sole example of
C++ --> C translation?  

One way of looking at it is that cfront is a compromise between two distinct
design goals:  (1) produce "correct", efficient C code from C++ code, and
(2) produce C code which is as much like the original C++ code as possible,
and thus is still fairly "human-readable".  Most "true" compilers are only
concerned with (1).  Note that (2) is much easier than (1), for translations
to both C and assembly language.

For example, people say that inline functions in G++ are "compiled in",
whereas they don't tend to say this about inlines in cfront.  This is
because G++ inserts code with the appropriate semantics inline, whereas
cfront attempts to simply copy the appropriate code in without fully
understanding its semantics, thus introducing significant restrictions in
"inlineability".  My definition of "true" compilation would involve the
process of semantic analysis followed by "from scratch" code generation.

One can imagine writing a back-end for GNU G++ which produced C-code (in
fact some friends and I have partially completed such a beast).  I would
call this hypothetical machine a "true" compiler, but cfront a "translator",
though they both translate C++ to C.

					Bart Massey
					..tektronix!videovax.tek.com!bart
					..tektronix!reed.bitnet!bart

DISCLAIMER:  The above is not intended to imply that there's anything wrong
with cfront -- there are situations in which it is much more useful than a
"true" compiler.  It is merely intended to point out distinctions between
cfront and "true" compilers.

ark@alice.UUCP (Andrew Koenig) (04/18/89)

In article <5408@videovax.tv.Tek.com>, bart@videovax.tv.Tek.com (Bart Massey) writes:

> One way of looking at it is that cfront is a compromise between two distinct
> design goals:  (1) produce "correct", efficient C code from C++ code, and
> (2) produce C code which is as much like the original C++ code as possible,
> and thus is still fairly "human-readable".  Most "true" compilers are only
> concerned with (1).  Note that (2) is much easier than (1), for translations
> to both C and assembly language.

Cfront is only concerned with (1).

> For example, people say that inline functions in G++ are "compiled in",
> whereas they don't tend to say this about inlines in cfront.  This is
> because G++ inserts code with the appropriate semantics inline, whereas
> cfront attempts to simply copy the appropriate code in without fully
> understanding its semantics, thus introducing significant restrictions in
> "inlineability".  My definition of "true" compilation would involve the
> process of semantic analysis followed by "from scratch" code generation.

I'm not sure what you're trying to say here.  Are you saying that
cfront inline expansion is often incorrect?  If so, you're wrong.
Are you saying that cfront handles inline functions by macro-expansion
on C++ source text?  If so, your're wrong there too.

Any C++ compiler that attempts inline expansion without `understanding
its semantics' will find that a recursive call of an inline function
will, um, throw it for a loop.

> One can imagine writing a back-end for GNU G++ which produced C-code (in
> fact some friends and I have partially completed such a beast).  I would
> call this hypothetical machine a "true" compiler, but cfront a "translator",
> though they both translate C++ to C.

Why?  Cfront does everything a GNU C++ that produces C would.  It does
the same kind of complete syntax and semantic analysis that any compiler
does, resulting in an internal data structure that it traverses to
produce C.  If it didn't do a full analysis, it would routinely
translate erroneous C++ programs into erroneous C programs --
but it doesn't.

There are only two ways in which cfront tries to make that C similar
to the input C++: it maintains a close correspondence between C++
external names and C external names (to facilitate linkage between
C and C++ programs) and it tries to translate each C++
expression-statement into a single C expression-statement
(mostly for reasons of efficiency and convenience).

Aside from that, I can assure you that the easiest way to understand
the C code generated by cfront is to translate it into assembly language
and read that.
-- 
				--Andrew Koenig
				  ark@europa.att.com

kearns@read.columbia.edu (Steve Kearns) (04/18/89)

One of Bjarne's stated principles with C++ was:
(*) When faced with the possibility of making the language
	(and manual) simpler by making the compiler more complicated,
	do it.

While I think that compiling to C is a fine idea, ATT cripples
the idea by requiring the translation to take place in a 
"close to recursive" way.  Specifically, every C++ statement must
translate into an equivalent C statement.  
(This was reported by Andrew Koenig
at a talk here).  The upshot of this design desicision is that
instead of using C as a fancy assembly language, ATT is trying
to write a "simple" translator to C.  

This is a bad decision, and goes against the priniciple outlined
above.  An example of this is their implementation of inline
functions, which inlines functions EXCEPT IF THINGS GET A LITTLE
COMPLICATED.  

So, I would suggest keeping the c++ -> c translation, but using
c as an assembly language instead of using "recursive translation".

leech@zeta.cs.unc.edu (Jonathan Leech) (04/19/89)

In article <9212@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes:
>Aside from that, I can assure you that the easiest way to understand
>the C code generated by cfront is to translate it into assembly language
>and read that.

    Disagree.  The C output is actually pretty easy to read if it's
indented properly, excess parenthesis removed, and the variable names
unmunged.
--
    Jon Leech (leech@cs.unc.edu)    __@/
    ``Those what cannot remedy the past can pretend to repeal it."
	- Attributed to Santa Ana by Howland Owl

nsds@mbunix.mitre.org (Neil S. Smith) (04/19/89)

In article <173@cs.columbia.edu> jordan@cs.columbia.edu (Jordan Hayes) writes:
>Say you don't have a C++ compiler for a certain kind of machine,
>but you do have a C compiler.
>Can you get g++ or cfront to generate C on the Sun and have the
>unnamed machine compile that?

Even if cfront does generate C-compilable code, and the code is
compiled and linked on the target machine, there is still the problem
of static object constructors and destructors.  The AT&T system (and
most systems derived from it, I imagine), injects calls to the
constructors and destructors of static objects into either the linked
executable or the object files (before linking), depending on the
system used.  This is the 'munch' phase of translation.

It seems to me insufficient simply to turn C++ into C via cfront and
compile the C code on the target machine, without also providing for
the inclusion of calls to static object constructors and destructors.

				neil smith
				(nsds@mitre.org)

---------------------
Neil Smith                              "Relax, don't worry, have a homebrew!"
The MITRE Corporation   M/S B310    Burlington Road         Bedford, MA  01730
Ma Bell:  (617) 271-8278                             Internet:  nsds@mitre.org

kurt@dsc.UUCP (Kurt Luoto x1006) (04/21/89)

In article <9212@alice.UUCP> ark@alice.UUCP (Andrew Koenig) writes:
>In article <5408@videovax.tv.Tek.com>, bart@videovax.tv.Tek.com (Bart Massey) writes:
>
>> [ ... stuff about AT&T cfront vs. G++ inline handling ommitted ... ]
>
>I'm not sure what you're trying to say here.  Are you saying that
>cfront inline expansion is often incorrect?  If so, you're wrong.
>Are you saying that cfront handles inline functions by macro-expansion
>on C++ source text?  If so, your're wrong there too.
>
> [ ... more defense of AT&T cfront inline handling ommitted ... ]
>
>      Cfront does everything a GNU C++ that produces C would.  It does
>the same kind of complete syntax and semantic analysis that any compiler
>does, resulting in an internal data structure that it traverses to
>produce C.  If it didn't do a full analysis, it would routinely
>translate erroneous C++ programs into erroneous C programs --
>but it doesn't.
>
>  [  ... ]
>
>				--Andrew Koenig
>				  ark@europa.att.com

This is not exactly a rebuttal,
but as a recent C++ (AT&T cfront 1.2.1) user, it did bring to mind
a bug that I discovered regarding its handling of inline functions
(forgive me if this has already been noted before).

The following C++ code:

   -------------------------------------------------------------
   // Sample program to show bugs in cfront inline expansion
   // in cfront 1.2.1  2/16/87.

   class foo {
      int  x ,y ;
      void  setXY( int k ) ;
   public:
      foo() { x = y = 0 ; }
      void  bar( ) ;
      };

   inline void  foo::setXY( int k ) {
      x = k ;
      y = k ;
      }

   void  foo::bar( ) {
      setXY( x + 1 );
      }
   -------------------------------------------------------------

produces the following C code as output
(edited slightly to make more readable to humans):

   -------------------------------------------------------------
   /* <<cfront 1.2.1 2/16/87>> */
   struct foo {	/* sizeof foo == 8 */
      int _foo_x ;
      int _foo_y ;
      };

   char _foo_setXY ();
   char _foo_bar ();

   char _foo_bar (_au0_this )
      struct foo *_au0_this ;
      { 
      (  (_au0_this -> _foo_x = (_au0_this -> _foo_x + 1 )),
	 (_au0_this -> _foo_y = (_au0_this -> _foo_x + 1 ))  ) ;
      } ;

   /* the end */
   -------------------------------------------------------------

The semantics of a procedure call have not been accurately reproduced
with this inline expansion.
It is clear from the C++ code that the routine foo::setXY() should set
both member fields x and y to the same value.
However, as expanded inline in the body of foo::bar(), field y will wind up
with a value one greater than that of field x.

By the way, is there yet a published bug list for cfront 1.2.1 ?
Is there a more recent version that fixes this and other bugs?

-------
Kurt Luoto   (neophyte news-poster)
(If I knew my e-mail address, I'd give it.)