Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!BORIS.TYMNET.COM!roberts From: roberts@BORIS.TYMNET.COM (Michael Roberts) Newsgroups: gnu.g++.bug Subject: G++ Library Implementation Error Message-ID: <8912062310.AA00481@boris.Tymnet.COM> Date: 6 Dec 89 23:10:50 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 196 Dear Doug Lea - dl@rocky.oswego.edu cc: bug-g++@prep.ai.mit.edu I am a new user of g++ version 1.35.0 and libg++ version 1.35.1. I greatly appreciate the flexible container classes in that library. I have a possible implementation error to report. In the jargon of the GNU C++ Library manual, chapter 33, bottom of page 105, the bug apears to be in d.del(k) of a particular Map class that I have used: Integer.String.AVLMap. The problem is that when I have a Map of 3 (or more) nodes, deleting the second node causes the first node to have its contents replaced by the contents of the departing second node; the contents of the third (and later) node(s) are unchanged. I obtained the Map class in the following manner. I generated the files Integer.String.Map.h and Integer.String.Map.cc via the genclass call genclass -2 Integer val String ref Map I generated the files Integer.String.AVLMap.h and Integer.String.AVLMap.cc via the call genclass -2 Integer val String ref AVLMap In order to get my code to compile, I had to make some changes to those files. I have run diff on all four, yielding four difference files which I have included in this e-mailing: Integer.String.Map.h.patch Integer.String.Map.cc.patch Integer.String.AVLMap.h.patch Integer.String.AVLMap.cc.patch Those .patch files are stuffed into patch.shar at the end of this message. Source code name (code appears below): g07.cc Compiler command line: g++ -g g07.cc Integer.String.Map.o Integer.String.AVLMap.o Execution and output: boris% a.out Key Contents ___ ________ 1 two 3 three boris% So we put in 3 Strings, deleted the second one, and the contents of the first one is overwritten with the second one's contents. The output should have been: Key Contents ___ ________ 1 one 3 three I am running on a Sun 3/280 under SunOS 4.0.3 The g++ compiler is version 1.35.0 (as opposed to the library, which is 1.35.1). I hope that's enough to help you find the problem. Thanx! -Mike Michael G. Roberts | Internet: roberts@calvin.Tymnet.COM BT Tymnet, Inc | UUCP: {ames,sun}!oliveb!tymix!roberts 2560 North First Street | Voice: 408-922-7931 P.O.Box 49019, San Jose, CA 95161-9019 | Fax: 408-922-6125 ---------- The Source Code ---------- #include #include "String.h" #include "Integer.h" #include "Integer.String.AVLMap.h" main() { IntegerStringAVLMap ISM("empty"); // default contents "empty" ISM[Integer(1)] = String("one"); ISM[Integer(2)] = String("two"); ISM[Integer(3)] = String("three"); ISM.del(Integer(2)); // HERE IT IS!!! cout << "\nKey Contents\n___ ________\n"; // output all the strings in the IntegerStringAVLMap for (Pix i = ISM.first(); i != 0; ISM.next(i)) cout << ISM.key(i) << " " << ISM.contents(i) << "\n"; cout << "\n"; ISM.OK(); } /* main */ ---------- patch.shar ---------- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'Integer.String.AVLMap.cc.patch' <<'END_OF_FILE' X0a1,2 X> // 12-04-89 Added IntegerCMP X> X25a28,29 X> #include "Integer.h" X> #include "String.h" X111a116,122 X> // From the usage of IntegerCMP results it is clear that cmp is to be X> // loaded with 0 iff key == t->item. That is the semantics of !=. But X> // there is the additional problem of the condition for returning a value X> // < 0, which I do not understand. Perhaps compare(Integer&,Integer&) is X> // the better choice. Yes! <0 means arg1 < arg2. This fits AVL being an X> // ordered Map. X> inline int IntegerCMP(Integer& key, Integer& item) {return compare(key, item);} END_OF_FILE if test 586 -ne `wc -c <'Integer.String.AVLMap.cc.patch'`; then echo shar: \"'Integer.String.AVLMap.cc.patch'\" unpacked with wrong size! fi # end of 'Integer.String.AVLMap.cc.patch' fi if test -f 'Integer.String.AVLMap.h.patch' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Integer.String.AVLMap.h.patch'\" else echo shar: Extracting \"'Integer.String.AVLMap.h.patch'\" \(0 characters\) sed "s/^X//" >'Integer.String.AVLMap.h.patch' <<'END_OF_FILE' END_OF_FILE if test 0 -ne `wc -c <'Integer.String.AVLMap.h.patch'`; then echo shar: \"'Integer.String.AVLMap.h.patch'\" unpacked with wrong size! fi # end of 'Integer.String.AVLMap.h.patch' fi if test -f 'Integer.String.Map.cc.patch' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Integer.String.Map.cc.patch'\" else echo shar: Extracting \"'Integer.String.Map.cc.patch'\" \(622 characters\) sed "s/^X//" >'Integer.String.Map.cc.patch' <<'END_OF_FILE' X0a1,2 X> // 12-04-89 Corrected ::seek X> X24a27,28 X> #include "Integer.h" X> #include "String.h" X41a46 X> #if 0 X42a48,58 X> #else X> // This loop advances the Pix index i from first to last, each time checking X> // that have not reached either the end of the Map or the desired key value X> // item. The missing function IntegerEQ must be supplied. Integer.h has X> // the following functions to choose from: X> // compare signed comparison X> // ucompare unsigned comparison not appropriate here X> // == X> // != I'll try this one X> for (Pix i = first(); i != 0 && (key(i) != item); next(i)); X> #endif END_OF_FILE if test 622 -ne `wc -c <'Integer.String.Map.cc.patch'`; then echo shar: \"'Integer.String.Map.cc.patch'\" unpacked with wrong size! fi # end of 'Integer.String.Map.cc.patch' fi if test -f 'Integer.String.Map.h.patch' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Integer.String.Map.h.patch'\" else echo shar: Extracting \"'Integer.String.Map.h.patch'\" \(94 characters\) sed "s/^X//" >'Integer.String.Map.h.patch' <<'END_OF_FILE' X30c30,31 X< #include "Integer.defs.h" X--- X> //#include "Integer.defs.h" X> #include "Integer.h" END_OF_FILE if test 94 -ne `wc -c <'Integer.String.Map.h.patch'`; then echo shar: \"'Integer.String.Map.h.patch'\" unpacked with wrong size! fi # end of 'Integer.String.Map.h.patch' fi echo shar: End of shell archive. exit 0