[comp.sys.att] G++ on the Unix PC

jeffl@berick.uucp (Jeff Lawhorn) (12/30/89)

I am attempting to port g++ 1.36.1 to the UnixPC.  I have gotten
it to compile, but when I feed it the following source, it gives
me error messages.  (The same version of g++ running on a sun
gives the correct results.)


	class x {
		public:
			x() {}
			~x() {}
	};

	int main(int argc, char *argv[])
	{	
		x y;

		return(0);
	}

When I run g++, I get the following results:

berick!jeffl(users) 141> g++ -v testit.cc
gcc version 1.36.1- (based on GCC 1.36)
 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68k -Dunix -Dunixpc -D__mc68k__ -D__unix__ -D__unixpc__ testit.cc /usr/tmp/cca13036.cpp
GNU CPP version 1.36
 /usr/local/lib/gcc-cc1plus /usr/tmp/cca13036.cpp -quiet -dumpbase testit.cc -version -o /usr/tmp/cca13036.s
GNU C++ version 1.36.1- (based on GCC 1.36) (68k, SGS/AT&T unixpc syntax) compiled by GNU C version 1.36.
default target switches:
testit.cc: In method x::x ():
testit.cc:4: parse error at null character
testit.cc:12: return from a constructor: use `this = ...' instead
berick!jeffl(users) 142> 


Anyone have sugestions on where to start looking for the cause of
this?  Also, if I change the constructor/destructor to be forward
references, and define the actual functions somewhere else, then
it seems to work.

Any light anyone can shed on this would be greatly appreciated
since I can not get sdb to work on an executable the size of g++.
--

Jeff Lawhorn                 I know I had a pithy quote sitting 
jeffl@berick.uucp            around here somewhere...
ucsd!sdsu!berick!jeffl       
-- 

Jeff Lawhorn                 I know I had a pithy quote sitting 
jeffl@berick.uucp            around here somewhere...
ucsd!sdsu!berick!jeffl       

rfg@ics.uci.edu (Ron Guilmette) (12/31/89)

In article <JEFFL.89Dec29225441@berick.uucp> jeffl@berick.uucp writes:
>I am attempting to port g++ 1.36.1 to the UnixPC.  I have gotten
>it to compile, but when I feed it the following source, it gives
>me error messages.  (The same version of g++ running on a sun
>gives the correct results.)
>
>
>	class x {
>		public:
>			x() {}
>			~x() {}
>	};
>
>	int main(int argc, char *argv[])
>	{	
>		x y;
>
>		return(0);
>	}
>
>When I run g++, I get the following results:
>
>berick!jeffl(users) 141> g++ -v testit.cc
>gcc version 1.36.1- (based on GCC 1.36)
> /usr/local/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68k -Dunix -Dunixpc -D__mc68k__ -D__unix__ -D__unixpc__ testit.cc /usr/tmp/cca13036.cpp
>GNU CPP version 1.36
> /usr/local/lib/gcc-cc1plus /usr/tmp/cca13036.cpp -quiet -dumpbase testit.cc -version -o /usr/tmp/cca13036.s
>GNU C++ version 1.36.1- (based on GCC 1.36) (68k, SGS/AT&T unixpc syntax) compiled by GNU C version 1.36.
>default target switches:
>testit.cc: In method x::x ():
>testit.cc:4: parse error at null character
...

First let me point out that gnu.g++ is *not* the right place to be posting
bug reports!  Please post bug reports (or questions about possible bugs)
to gnu.g++.bug instead.

Now on to your problem.

There is a general problem with SystemV-based systems which tends to
result in error messages of the form `parse error at null character'.
The problem is that the standard SystemV setvbuf() routine is brain-
dammaged.  This *only* causes problems when the compiler is attempting
to inline-expand very small function bodies (such as the constructor
for class x shown above, which is being quietly inlined at the point at
which the object `y' is declared).

I have tried to fix-up the code in cplus-lex.c in a general way that should
prevent this problem from arising on most types of SystemV-based systems.
The following patches implement my fixes for a hacked-up version of g++
1.36.1.  (Your line numbers may vary).

I hope that these patches will be incorporated into g++ 1.36.2.  This is
fairly important because right now, g++ is broken for most SystemV's.
Somebody should check however to see that I didn't break the code for
hp9000's (which appear to be a special case).

Thanks to Andrew Klossner @ Tektronix for pointing out the brain-dammage
in setvbuf() on USG.  Comments in the patches describe the nature of the
brain-dammage in more detail.

Enjoy,

// rfg

diff -rc2 1.36.1-/cplus-lex.c 1.36.1+/cplus-lex.c
*** 1.36.1-/cplus-lex.c	Thu Nov  2 23:14:34 1989
--- 1.36.1+/cplus-lex.c	Fri Nov 24 17:53:57 1989
***************
*** 980,1000 ****
        pending_inlines = pending_inlines->next;
        finput = finput2;
! #if defined(i386) && !defined(sequent) && !defined(sun386)
!       finput2->_ptr = finput2->_base = t->buf;
!       _bufend(finput2) = t->buf + t->len;
!       finput2->_flag = _IOFBF | _IOREAD;
!       finput2->_cnt = t->len - 1;
! #else
! #ifndef hp9000s300
! #ifdef USG_STDIO
        setvbuf(finput2,t->buf,_IOFBF,t->len);
        finput2->_cnt = t->len-1;
  #else
        setbuffer (finput2, t->buf, t->len);
        finput2->_cnt = finput2->_bufsiz - 1;
- #endif				/* USG_STDIO */
- #else
-       setvbuf(finput2,t->buf,_IOFBF,t->len);
-       finput2->_cnt = t->len-1;
  #endif
  #endif
--- 980,1003 ----
        pending_inlines = pending_inlines->next;
        finput = finput2;
! 
! #if defined(hp9000s300)
!       /* The hp9000 has a working setvbuf() routine.  */
        setvbuf(finput2,t->buf,_IOFBF,t->len);
        finput2->_cnt = t->len-1;
  #else
+ #if defined(USG) || defined(DGUX)
+       /* The standard SystemV code has a broken version of the setvbuf()
+          routine.  IF you try to setvbuf to a buffer which is shorter
+          than 8 bytes, then the standard USG setvbuf() will ignore the
+          request and malloc its own buffer.  This totally screws up things
+          for g++, so don't use setvbuf() on USG systems.  */
+       finput2->_ptr = finput2->_base = (unsigned char *) t->buf;
+       _bufend(finput2) = (unsigned char *) t->buf + t->len;
+       finput2->_flag = _IOFBF | _IOREAD;
+       finput2->_cnt = t->len - 1;
+ #else
+       /* Typical BSD systems can use setbuffer.  */
        setbuffer (finput2, t->buf, t->len);
        finput2->_cnt = finput2->_bufsiz - 1;
  #endif
  #endif
***************
*** 2078,2098 ****
  		 end of this function.  */
  	      pending_inlines = pending_inlines->next;
! #if defined(i386) && !defined(sequent) && !defined(sun386)
! 	      finput2->_ptr = finput2->_base = t->buf;
! 	      _bufend(finput2) = t->buf + t->len;
! 	      finput2->_flag = _IOFBF | _IOREAD;
! 	      finput2->_cnt = t->len - 1;
! #else
! #ifndef hp9000s300
! #ifdef USG_STDIO
        	      setvbuf(finput2,t->buf,_IOFBF,t->len);
         	      finput2->_cnt = t->len-1;
  #else
    	      setbuffer (finput2, t->buf, t->len);
    	      finput2->_cnt = finput2->_bufsiz - 1;
- #endif				/* USG_STDIO */
- #else
-       	      setvbuf(finput2,t->buf,_IOFBF,t->len);
-        	      finput2->_cnt = t->len-1;
  #endif
  #endif
--- 2081,2100 ----
  		 end of this function.  */
  	      pending_inlines = pending_inlines->next;
! #if defined(hp9000s300)
!               /* The hp900s300 has a working setvbuf() routine.  */
        	      setvbuf(finput2,t->buf,_IOFBF,t->len);
         	      finput2->_cnt = t->len-1;
  #else
+ #if defined(USG) || defined (DGUX)
+               /* The standard USG setvbuf() routine screws up if the buffer
+                  you give it is smaller that 8 bytes, so don't use it.  */
+ 	      finput2->_ptr = finput2->_base = (unsigned char *) t->buf;
+ 	      _bufend(finput2) = (unsigned char *) t->buf + t->len;
+ 	      finput2->_flag = _IOFBF | _IOREAD;
+ 	      finput2->_cnt = t->len - 1;
+ #else
+               /* The typical BSD system can use setbuffer */
    	      setbuffer (finput2, t->buf, t->len);
    	      finput2->_cnt = finput2->_bufsiz - 1;
  #endif
  #endif

ebh@argon.UUCP (Ed Horch) (03/21/90)

In article <1990Mar19.030337.1860@chinet.chi.il.us> kdb@chinet.chi.il.us (Karl Botts) writes:
>>|>	Next question: Has anybody done g++ for the Unix PC yet? I don't have
>
>Well, I wouldn't call it trivial but I believe it can be done.  I have the
>compiler compiled and am about to tackle the lib.

A word of warning to anyone about to tackle this:  Don't even think
about using GCC source older than 1.37.1, and G++ source older than
1.37.0.  GCC 1.37.1 compiles painlessly on the Unix PC, and G++
compiles with a little prodding.  Also, you must have libg++ 1.37.0,
since it contains the runtime support G++ needs.  (I'd like to
actually have two libraries - one for runtime support, the
"necessities", and one for the application-oriented classes.)

>One big problem is the short supply of virtual memory; to compile the
>parser I had to shut everything else down -- especially uucp -- and source
>a script produced with make -n.  It fails from inside make, or even if you
>run the script in a subshell --- the normal way.  I am thus afraid that I
>am right on the bubble of not being able to compile the next version at
>all.

I have succcessfully compiled G++, and the library libg++, and have
produced an executable "hello world" program with it.

Compiling the Bison output blew when trying to optimize that huge
switch for all the states.  Turning off optimization fixed that,
although the executable is probably a lot bigger than it should be.  I
also compiled everything without -g.  In any case, I did this on argon
with everything else running normally (n.b. argon is 1.5x67).

Here are a few gotchas.  I'll post a more complete set of details when
I get everything stabilized.

1.  The VM problem.  See above.

2.  The makelinks script doesn't work right.  I had to link a lot of
    things over from the GCC directory by hand.

3.  I had to link /usr/include/fcntl.h to /usr/include/sys/fcntl.h.

4.  Collect had a bug where the globals __CTOR_LIST__ and
    __DTOR_LIST__ had extra underscores prepended to them.

5.  For some reason, ld, when called by g++, can't find the libraries
    in /usr/lib.  running g++ with -nostdlib, and adding in -L /usr/lib 
    worked around this.

6.  The Unix PC assembler doesn't like either $ or . in symbols.  In
    cplus-tree.h there are a bunch of #defines that expect to be able
    to use one or the other.  The Unix PC assembler manual says that
    you can use - in symbols, but the assembler didn't take them.  I
    manually hacked in a section that used Z as that special
    character, at the risk of polluting the global name space.

7.  Some of the libg++ files have names >14 characters.  In
    particular, files that are 15 characters long and end in .cc are
    misinterpreted as .c files.  I fixed these by hand.  Header files
    with long names didn't seem to be a problem.

8.  Major nastiness!  As compiled on argon, G++ complains of a parse
    error anywhere a function is defined inside a class definition,
    even if it's an empty function.  In String.h, SampleStatistic.h,
    SampleHistogram.h, and xyzzy.cc, things that look like this:

        class Foo
        {
            Foo()  {}
            ~Foo()  {}
            int zero()  { return 0; }
        };

    have to be changed to

        class Foo
        {
            Foo();
            ~Foo();
            int zero();
        };

        inline Foo::Foo() {}
        inline Foo::~Foo() {}
        inline Foo::zero() { return 0; }

Those are all the major things I encountered.  Note also that on
argon, the compiler took seven hours to build.  This would likely be a
lot faster on a system with more RAM than I have, though.  In any
case, it looks like G++ on the Unix PC is a reality.

>I know this has been discussed before, but is there any way to get more
>than 4Meg VM on this machine?

Actually, the limits are 4MB of physical RAM, and 2.5MB of per-process
virtual memory.

>Anyhow, re. g++; hang tough, we're working on it.

Me too.  It would be helpful if we could get the gnu.* groups here on
argon, since they've probably encountered the same problems we have,
and likely some we haven't seen.  If possible, I'd also like to
contribute whatever real fixes I make to the general distribution.

Lastly, muchas gracias to Alex Crain for his work with GCC on the Unix
PC, which has made the work for G++ much easier.

-Ed