[gnu.g++] CFRONT braindamaged?

mdt@YAHI.STANFORD.EDU (Michael Tiemann) (02/20/89)

Here's how not to fix a C++ problem.

   dave@andromeda.rutgers.edu (Dave Bloom) writes:

   >Hi there. We're running AT&T's C++ Ver 1.2.1, and as far as I'm
   >concerned, the following should work hunky-dorey. Does anybody
   >see anything wrong with my syntax?

   tnosoes!tom@uunet.uu.net (Tom Vijlbrief) responds:

   Yes, gnu g++ 1.32 reports:
   t.c:8: assignment between incompatible pointer types
   t.c:9: assignment between incompatible pointer types
   t.c:10: assignment between incompatible pointer types

Without context, we must assume this is correct.  Ok.

   This can be corrected:
   ======================
	  class zz {
	      public:
		   void    (zz::* xx)(char *);
		  void a(char* s) { printf("function a: %s\n", s); }
		  void b(char* s) { printf("function b: %s\n", s); }
		  void c(char* s) { printf("function c: %s\n", s); }
		  zz(int i) {
			  if(i==0)        xx= &(zz::a);
			  else if(i==1)   xx= &(zz::b);
			  else            xx= &(zz::c);
			  } 
	  };
	  main()
	  {
		  zz dave(1);
		  dave.xx("Yes!!!");
	  } 

   ==========
   This produces:

   t.c:17: invalid call via pointer-to-member function

Which is a correct error message.  The expression `dave.xx' resolves
to a pointer to member function.  In order to apply this as a
function, you must have an object associated with it.

   Changing the code to:

	  class zz {
	      public:
		   void    (zz::* xx)(char *);
		  void a(char* s) { printf("function a: %s\n", s); }
		  void b(char* s) { printf("function b: %s\n", s); }
		  void c(char* s) { printf("function c: %s\n", s); }
		  void e() { xx(this, "yes"); }
		  zz(int i) {
			  if(i==0)        xx= &(zz::a);
			  else if(i==1)   xx= &(zz::b);
			  else            xx= &(zz::c);
			  } 
	  };
	  main()
	  {
		  zz dave(1);
		  dave.e();
	  } 
   ======
   produces the correct result.

At the cost of replacing a call to a parameterized function with a
call to an unparameterized function which calls the parameterized
function with a hard-wired result.  This is not what C++ people should
be doing to their code.  To show how dangerous such a practice can be,
notice that in the first case, the call was intended to take the
parameter "Yes!!!", but when rewritten, the parameter "yes" is
eventually passed.  A better solution is to fix the erroneous call:

	(dave.*(dave.xx)) ("Yes!!!");

   Tom
   ===============================================================================
   Tom Vijlbrief
   TNO Institute for Perception
   P.O. Box 23				Phone: +31 34 63 62 77
   3769 ZG  Soesterberg			E-mail: tnosoes!tom@mcvax.cwi.nl
   The Netherlands				    or:	uunet!mcvax!tnosoes!tom
   ===============================================================================

Part of the blame for this problem lies with GNU C++: better error
reporting by the compiler would help people correct their errors,
rather than trying something else, and seeing whether it will shut up
the compiler.  If anyone wants to design a better error reporting
facility for this compiler, the position is still open.

Michael