Path: utzoo!utgpu!watmath!uunet!tut.cis.ohio-state.edu!CENTRAL.SUN.COM!xochitl!cheeks From: xochitl!cheeks@CENTRAL.SUN.COM (Mark Costlow) Newsgroups: gnu.g++.bug Subject: G++ enum problem, Version 1.35.0, Sun4-os4.0.3 Message-ID: <8907241933.AA03144@xochitl.uucp> Date: 24 Jul 89 19:33:33 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 415 [sorry if you've seen this before. I mistakenly posted it instead of sending it to the mailing list] Following is a description of what we believe to be a bug in g++ 1.35.0. This is on a Sun4 under SunOS 4.0.3. The bug in g++ apparently works like this. In a method that has a typedef'ed enum as an argument, that parameter is encoded in the method's function name as _$E_n, where "n" indicates that this is the nth enum that has been typedef'ed. When a library is complied that defines numerous enum types in different modules, they each generate _E_0 when they are used as arguments because the compiler doesn't see all the enums at once. But when an application refers to more than one of these modules, the enums begin generating different function names. The workaround I came up with was to change typedef enum { X, Y, Z ... } NewType; to typedef int NewType; enum { X, Y, Z ... } ; The real fix would be to include the type name in the function name instead of the index - eg. "_E_NewType" instead of "_E_0". Run the rest of this message through sh to extract the test case t hat I worked up along with a sample run. (It compiles under cfront but not g++). Mark Costlow ....texsun!xochitl!cheeks #---------------------------------- cut here ---------------------------------- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by on Fri Jul 21 17:08:43 1989 # # This archive contains: # testdir # # Existing files will not be overwritten. # Error checking via wc(1) will be performed. LANG=""; export LANG echo mkdir - testdir mkdir testdir if test -f testdir/test_class_one.c then echo Ok to overwrite existing file testdir/test_class_one.c\? read answer case "$answer" in [yY]*) echo Proceeding;; *) echo Aborting; exit 1;; esac rm -f testdir/test_class_one.c if test -f testdir/test_class_one.c then echo Error: could not remove testdir/test_class_one.c, aborting exit 1 fi fi echo x - testdir/test_class_one.c cat >testdir/test_class_one.c <<'@EOF' #include #include "test_class_one.h" test_class_one::test_class_one() { printf("I don't do anything\n"); }; test_class_one::~test_class_one() { printf("Neither do I\n"); }; void test_class_one::test_func_one(NewTypeOne i) { printf("Got %d\n", i); }; @EOF set `wc -lwc testdir/test_class_one.h <<'@EOF' typedef enum {A, B, C} NewTypeOne; class test_class_one { public: test_class_one(); ~test_class_one(); void test_func_one(NewTypeOne); }; @EOF set `wc -lwc testdir/test_class_two.c <<'@EOF' #include #include "test_class_two.h" test_class_two::test_class_two() { printf("I don't do anything\n"); }; test_class_two::~test_class_two() { printf("Neither do I\n"); }; void test_class_two::test_func_two(NewTypeTwo i) { printf("Got %d\n", i); }; @EOF set `wc -lwc testdir/test_class_two.h <<'@EOF' typedef enum {X, Y, Z} NewTypeTwo; class test_class_two { public: test_class_two(); ~test_class_two(); void test_func_two(NewTypeTwo); }; @EOF set `wc -lwc testdir/test_code.c <<'@EOF' #include #include "test_class_one.h" #include "test_class_two.h" main() { test_class_one *tc1 = new test_class_one; test_class_two *tc2 = new test_class_two; cout << "Hello world ...\n"; tc1->test_func_one(A); tc2->test_func_two(X); cout << "Hello again ...\n"; tc1->test_func_one(B); tc2->test_func_two(Y); cout << "Hello for the last time ...\n"; tc1->test_func_one(C); tc2->test_func_two(Z); } @EOF set `wc -lwc testdir/test_code.h <<'@EOF' typedef enum {A, B, C} NewTypeOne; typedef enum {X, Y, Z} NewTypeTwo; @EOF set `wc -lwc testdir/Makefile <<'@EOF' CC = g++ -v OBJS = test_code.o test_class_one.o test_class_two.o all: clean test_code test_code: $(OBJS) $(CC) -o test_code $(OBJS) test_code.o: test_code.c $(CC) -c test_code.c test_class_one.o: test_class_one.c $(CC) -c test_class_one.c test_class_two.o: test_class_two.c $(CC) -c test_class_two.c clean: rm -f *.o test_code @EOF set `wc -lwc testdir/Sample_Run <<'@EOF' Script started on Fri Jul 21 16:37:36 1989 [1] ->make CC="CC -v" rm -f *.o test_code CC -v -c test_code.c CC test_code.c: cc -c -v test_code..c /lib/cpp -undef -Dunix -Dsun -Dsparc test_code..c >/tmp/cpp.07149.0.i /lib/ccom - /tmp/ccom.07149.1.s rm /tmp/cpp.07149.0.i /bin/as -o test_code..o -Q /tmp/ccom.07149.1.s rm /tmp/ccom.07149.1.s CC -v -c test_class_one.c CC test_class_one.c: cc -c -v test_class_one..c /lib/cpp -undef -Dunix -Dsun -Dsparc test_class_one..c >/tmp/cpp.07161.0.i /lib/ccom - /tmp/ccom.07161.1.s rm /tmp/cpp.07161.0.i /bin/as -o test_class_one..o -Q /tmp/ccom.07161.1.s rm /tmp/ccom.07161.1.s CC -v -c test_class_two.c CC test_class_two.c: cc -c -v test_class_two..c /lib/cpp -undef -Dunix -Dsun -Dsparc test_class_two..c >/tmp/cpp.07173.0.i /lib/ccom - /tmp/ccom.07173.1.s rm /tmp/cpp.07173.0.i /bin/as -o test_class_two..o -Q /tmp/ccom.07173.1.s rm /tmp/ccom.07173.1.s CC -v -o test_code test_code.o test_class_one.o test_class_two.o cc -o test_code -v test_code.o test_class_one.o test_class_two.o -lC /bin/ld -dc -dp -e start -X -o test_code /usr/lib/crt0.o test_code.o test_class_one.o test_class_two.o -lC -lc /bin/ld -dc -dp -e start -X -o test_code /usr/lib/crt0.o __ctdt.o test_code.o test_class_one.o test_class_two.o -lC -lc [2] ->./test_code I don't do anything I don't do anything Hello world ... Got 0 Got 0 Hello again ... Got 1 Got 1 Hello for the last time ... Got 2 Got 2 [3] ->make CC="g++ -v" rm -f *.o test_code g++ -v -c test_code.c g++ version 1.35.0 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ test_code.c /tmp/cca07208.cpp GNU CPP version 1.35 /usr/local/lib/gcc-cc1plus /tmp/cca07208.cpp -quiet -dumpbase test_code.c -noreg -version -o /tmp/cca07208.s GNU C++ version 1.35.0 (sparc) compiled by GNU C version 1.35. as /tmp/cca07208.s -o test_code.o g++ -v -c test_class_one.c g++ version 1.35.0 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ test_class_one.c /tmp/cca07212.cpp GNU CPP version 1.35 /usr/local/lib/gcc-cc1plus /tmp/cca07212.cpp -quiet -dumpbase test_class_one.c -noreg -version -o /tmp/cca07212.s GNU C++ version 1.35.0 (sparc) compiled by GNU C version 1.35. as /tmp/cca07212.s -o test_class_one.o g++ -v -c test_class_two.c g++ version 1.35.0 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ test_class_two.c /tmp/cca07216.cpp GNU CPP version 1.35 /usr/local/lib/gcc-cc1plus /tmp/cca07216.cpp -quiet -dumpbase test_class_two.c -noreg -version -o /tmp/cca07216.s GNU C++ version 1.35.0 (sparc) compiled by GNU C version 1.35. as /tmp/cca07216.s -o test_class_two.o g++ -v -o test_code test_code.o test_class_one.o test_class_two.o g++ version 1.35.0 /usr/local/lib/gcc-ld++ -o test_code -C /usr/local/lib/crt0+.o test_code.o test_class_one.o test_class_two.o -lg++ /usr/local/lib/gcc-gnulib -lc test_code.o: Undefined symbol _test_func_two_PStest_class_two_E$_1 referenced from text test_code.o: Undefined symbol _test_func_two_PStest_class_two_E$_1 referenced from text test_code.o: Undefined symbol _test_func_two_PStest_class_two_E$_1 referenced from text *** Error code 1 make: Fatal error: Command failed for target `test_code' [4] ->^D script done on Fri Jul 21 16:38:22 1989 @EOF set `wc -lwc