From: brm30@diag.amdahl.COM (Brian Moyle)
Subject: "cin" bug?
Organization: GNUs Not Usenet
Distribution: gnu
Date: Tue, 15 Sep 1992 01:06:41 GMT

Hello,

     I'm fairly new to C++ programming, but I've run into a little
problem that seems to qualify as a bug.  The following program was 
taken from The Waite Group's, "C++ Programming," by John Berry,
copyright 1988 (fourth printing -- 1990).  On page 44, the following
paragraph provides an explanation of how the 'while' loop is exited:

"The program also uses a trick to develop an easy user interface.
Recall that a character is actually an integer value.  Because
implicit type conversion is easy and unregulated in C++, the program
can accept as input the value 'exit.'  The 'e' is converted from its
integer representation into a real number.  The same thing happens to
the 'i'.  However, the value 'x' is stored in the character variable
'opr'.  This value then triggers the exit clause of the 'switch'."

     When I run this program, and type "exit" to terminate the loop, 
the program seems to ignore any future attempts at input via the "cin" 
routine.  Am I violating some rule in C++ which I don't yet understand?

     To the best of my knowledge, I am running gcc 2.2.2 on a Sun 
SPARCstation IPC.  Here are the results of compiling with the "-v" 
option:

~/c++_prog > gcc -v calc.C -lg++
Reading specs from /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/specs
gcc version 2.2.2
 /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/cpp -lang-c++ -v -undef
 -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -Dsparc -Dsun -Dunix
 -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix calc.C
 /usr/tmp/cca13438.i
GNU CPP version 2.2.2 (sparc)
 /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/cc1plus /usr/tmp/cca13438.i
 -quiet -dumpbase calc.cc -version -o /usr/tmp/cca13438.s
GNU C++ version 2.2.2 (sparc) compiled by GNU C version 2.2.2.
 as -o calc.o /usr/tmp/cca13438.s
 /usr/local/pswd/lib/gcc-lib/sun4/2.2.2/ld -e start -dc -dp
 /lib/crt0.o -L/usr/local/pswd/lib/gcc-lib/sun4/2.2.2
 -L/usr/local/pswd/lib calc.o -lg++ -lgcc -lc -lgcc

Also, this might be useful:

~/c++_prog > uname -a
   SunOS bmoyle 4.1.1 1 sun4c


Hopefully, this is enough information.  Please send any
recommendations to:

          brm30@diag.amdahl.com


Thanks, in advance, for the help!

Brian Moyle
(408)992-3185
brm30@diag.amdahl.com


*********************************************************************


program input/output:
----------------------------------------------------------------------
enter expression 5+3
x=5  y=3  opr=+
=8

enter expression 8*2
x=8  y=2  opr=*
=16

enter expression exit
x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

enter expression x=8  y=2  opr=*
=16

               .
               .      (continues until terminated)
               .

----------------------------------------------------------------------



program listing: calc.C
----------------------------------------------------------------------
#include <stream.h>

// define some useful substitutions

#define BLANK ' '
#define STOP 0

main ()
{
   double x,y,
          radd(double, double), // declare a simple add function,
          rsub(double, double), // ... a subtraction function,
          rmul(double, double), // ... multiplication, ...
          rdiv(double, double); // ... and finally, a division function.
   char opr = BLANK;      // declare a variable for the operator

   while (opr != STOP)  {       // continue until the user says "exit"
      cout << "enter expression ";   // prompt...
      cin >> x >> opr >> y;          // ... read ...

      // I added this line for "debugging"
      cout << "x=" << x << "  y=" << y << "  opr=" << opr << endl;

      switch (opr)  {      // ... and evaluate
         case '+' : cout << "=" << radd(x,y);   // create a clause for each
                    break;                      // operation
         case '-' : cout << "=" << rsub(x,y);
                    break;
         case '*' : cout << "=" << rmul(x,y);
                    break;
         case '/' : cout << "=" << rdiv(x,y);
                    break;
         case 'x' : opr = STOP;      //... a cheap trick, "x" is the
                    break;           // second letter in "exit"
         default  : cout << "not yet implemented!\n"; // unbounded optimism
         }  // switch

      cout << "\n\n";

   }  // while
}  // main()

//////////////////////////////////////////////////////////////////////

double radd(double a, double b)   // a function to add doubles
{
   return(a+b);
}

//////////////////////////////////////////////////////////////////////

double rsub(double a, double b)   // ... one to subtract them
{
   return(a-b);
}

//////////////////////////////////////////////////////////////////////

double rmul(double a, double b)   // ... multiply ...
{
   return(a*b);
}

//////////////////////////////////////////////////////////////////////

double rdiv(double a, double b)   // ... and divide
{
   if (b == 0)   // don't forget to check for division by zero.
      return 0;
   return(a/b);
}

//////////////////////////////////////////////////////////////////////

----------------------------------------------------------------------

Newsgroups: gnu.gcc.bug