gordon%stats.ucl.ac.uk@NSS.CS.UCL.AC.UK (Gordon Joly Statistics UCL) (02/04/89)
I have submitted this example before and was confident that the fix was OK. But I still cannot compile any of the code unless I change "class x" to "class z" throughout. Even then, the test fails. I am prepared to admit that the fault may lie at this end. But is it odd. I am using g++ and libg++.a version 1.32.0, under two configurations, a SUN-3/160 under 3.4 and SUN-3/50 under 4.0.1. Links on 3.4 OS are Linked `config.h' to `xm-m68k.h'. Linked `tm.h' to `tm-sun3+.h'. Linked `md' to `m68k.md'. Linked `aux-output.c' to `output-m68k.c'. Here is the error in the compilation. karl:/stats/staff/karl/gordon/c++/otto/workspace[85] make -n g++ -c x.cc g++ -c testing_prog.cc g++ -o testing_prog testing_prog.o x.o testing_prog 2> errors-prob_bitwise_copying > calling_sequence if [ -s errors-prob_bitwise_copying ]; then cat errors-prob_bitwise_copying; exit 1; else rm errors-prob_bitwise_copying; fi # calling seq check is only valid if previous check was OK awk -f check.awk calling_sequence > errors-sequencing if [ -s errors-sequencing ]; then cat errors-sequencing; exit 1; else rm errors-sequencing; fi # rm calling_sequence echo " - Passed test OK" karl:/stats/staff/karl/gordon/c++/otto/workspace[86] make g++ -c x.cc /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/builtin.h:71: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/builtin.h:72: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/builtin.h:73: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/builtin.h:74: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:133: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:134: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:247: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:248: warning: inline declaration ignored for function with `...' In function struct File &File::read (...): /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:249: parse error before `,' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:249: `n' was not declared (first use this function) /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:249: (Each undeclared identifier is reported only once /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:249: for each function it appears in.) /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:249: parse error before `)' At top level: /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:252: parse error before `x' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:253: warning: inline declaration ignored for function with `...' In function struct File &File::write (...): /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:254: parse error before `,' /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:254: `n' was not declared (first use this function) /stats/staff/karl/gordon/GNU/usr/ucl/lib/g++-include/File.h:254: parse error before `)' *** Error code 1 Stop. karl:/stats/staff/karl/gordon/c++/otto/workspace[87] Gordon Joly. Surface mail: Dr. G.C.Joly, Department of Statistical Science, University College London, Gower Street, LONDON WC1E 6BT, U.K. E-mail: | Tel: +44 1 387 7050 JANET (U.K. network) gordon@uk.ac.ucl.stats | extension 3636 (Arpa/Internet form: gordon@stats.ucl.ac.uk)| FAX: +44 1 387 8057 Relays: ARPA @nss.cs.ucl.ac.uk | EAN: @ean-relay.ac.uk | CSNET: %nss.cs.ucl.ac.uk@relay.cs.net | BITNET: %ukacrl.bitnet@cunyvm.cuny.edu, @ac.uk EARN: @ukacrl.bitnet, @AC.UK, @uk.ac.earn-relay By uucp/Usenet: ....!uunet!mcvax!ukc!stats.ucl.ac.uk!gordon -- Makefile start -- # to create & run "constructor/destructor" test for C++ # # To run test, just utter "make" in this directory. # # filenames for errors EBC=errors-prob_bitwise_copying ESEQ=errors-sequencing CC=g++ tests: testing_prog check.awk testing_prog 2> $(EBC) > calling_sequence if [ -s $(EBC) ]; then cat $(EBC); exit 1; else rm $(EBC); fi # calling seq check is only valid if previous check was OK awk -f check.awk calling_sequence > $(ESEQ) if [ -s $(ESEQ) ]; then cat $(ESEQ); exit 1; else rm $(ESEQ); fi # rm calling_sequence echo " - Passed test OK" testing_prog: x.h x.o testing_prog.o $(CC) $(CFLAGS) -o testing_prog testing_prog.o x.o testing_prog.o: x.h testing_prog.cc $(CC) $(CFLAGS) -c testing_prog.cc x.o: x.h x.cc $(CC) $(CFLAGS) -c x.cc clean: rm -f *.o *..c core calling_sequence $(EBC) $(ESEQ) clobber: clean rm -f testing_prog -- Makefile end -- # This is a shell archive, shar, format file. # To unarchive, feed this text into /bin/sh in the directory # you wish the files to be in. echo x - check.awk 1>&2 sed 's/^X//' > check.awk << 'End of check.awk' X# Check output from ctor/dtor test prog. X# X# Input is assumed to be a sequence of lines of the form: X# <routine-name> called; "this" = <address> X# X# An error is reported if, for any given address, the routine calls do not X# occur as in the following BNF: X# { ctor-call other-call* dtor-call }* X# (Constructor call includes initializers.) X# X# NB This awk script is relatively fragile - it does not validate its X# input, or do any other such checks for errors in the testing programs X# themselves. X# GPO 16/11/87 X# Minor mod (to tidy up prog slightly) GPO 24/11/87 X X { if (($1 == "x::x()") || ($1 == "x::x(x&)")){ # ctor X if (status[$5] == "defined"){ X print "ERROR: multiple use of address " $5 " on line " NR X } else { X status[$5] = "defined" X } X } else if ($1 == "x::~x()"){ # dtor X if (status[$5] != "defined"){ X print "ERROR: dtor called for unit'ed address " $5 " on line " NR X } else { X status[$5] = "undefined" X } X } else { # other X if (status[$5] != "defined"){ X print "ERROR: routine using unit'ed address " $5 " on line " NR X } X } X } XEND { for (a in status){ # check that all dtors have been called X if (status[a] == "defined"){ X print "ERROR: address " a " has not been dtor'ed by end of prog" X } X } X } End of check.awk chmod 755 check.awk echo x - testing_prog.cc 1>&2 sed 's/^X//' > testing_prog.cc << 'End of testing_prog.cc' X#include "x.h" X X// first some routines to play with ... X Xx Xf(x arg1, x arg2) X{ X x local1, local2, local3; X X return local2; X} X Xint Xintf(x arg1, x arg2) X{ X x local1, local2, local3; X X return 0; X} X Xx Xg() X{ X x local1, local2, local3; X X return local2; X} X Xx Xh() X{ X x local1, local2, local3; X X return local2; X} X Xx Xi(x arg) X{ X x local1, local2, local3; X X return local2; X} X X#ifndef pyr Xx Xdoubly_recursive(int depth_to_go) X{ X if (depth_to_go > 0){ X return(f(doubly_recursive(depth_to_go-1), X doubly_recursive(depth_to_go-1))); X } else { X x local; X return(local); X } X} X#endif X X// Now call the routines & see what happens ... Xint Xmain() X{ X // test for calling of ctors & dtors on nested calls ... X { X x local; X X local = f(g(),h()); X } X#ifndef pyr X // test for calling of ctors & dtors in recursive calls ... X doubly_recursive(3); X#endif X // test for calling of ctors & dtors in nested calls occurring in X // an expression X { X x a; X if (intf(i(g()),a)) X 7; X } X return 0; // ought to return true status, but ..... X} End of testing_prog.cc chmod 755 testing_prog.cc echo x - x.cc 1>&2 sed 's/^X//' > x.cc << 'End of x.cc' X// noddy class for testing purposes X// X// BEWARE: This file relies on being able to coerce a class pointer into X// a long so that it can be printed. X X#include "x.h" X#include <stream.h> X Xinline static void Xtell_world(char * who, x* address) X{ X cout << who << " called; \"this\" = " << (long) address << "\n"; X // Might be more convenient when debugging to use stderr, so that X // stays in sync with error messages - but test makefile assumes X // stdout. X} X Xinline static void Xerror_address_mismatch(char* routine, x* says, x* actual) X{ X cerr << "ERROR: address mismatch in call of " << routine X << "; class instance thought address was " << (long) says X << ", but it was actually " << (long) actual << "\n"; X} X Xx::x() X{ X tell_world("x::x()",this); X self = this; X} X Xx::x(x& xref) X{ X tell_world("x::x(x&)",this); X self = this; X if (xref.self != &xref) X error_address_mismatch("x::x(x&)",xref.self,&xref); X} X Xx& Xx::operator=(x& rhs) X{ X tell_world("x::operator=(x&)",this); X if (rhs.self != &rhs) X error_address_mismatch("x::operator=(x&)",rhs.self,&rhs); X if (self != this) X error_address_mismatch("x::operator=(x&)",self,this); X return(*this); X} X Xx::~x() X{ X tell_world("x::~x()",this); X if (self != this) X error_address_mismatch("x::~x()",self,this); X} End of x.cc chmod 755 x.cc echo x - x.h 1>&2 sed 's/^X//' > x.h << 'End of x.h' X// simplest class which completely avoids bitwise copying. X// good for testing calling of constructors and destructors. X Xclass x { X class x* self; // Note own address for testing/debugging purposes Xpublic: X x(); X x(x&); X x& operator=(x&); X ~x(); X}; End of x.h chmod 755 x.h