[comp.lang.c++] C++ 1.2.1 bug

jsimellon@cpsc.ucalgary.ca (Larry Mellon) (05/04/89)

We are running AT&T cfront 1.2.1 on Sun3s (OS 3.5), and have come across
the following problem:

When a temporary variable is created by cfront it opens a new block with
'{' before the C declaration of the temporary.  This is not a problem,
however the new block is only closed ('}') when another closing curly
is found, NOT when the temporary is no longer needed.  [Example is given
at end of posting].
This causes two errors, depending on the C compiler you have.

On Sun3 (OS3.5), cc gets a 'yacc: stack overflow error' after about
25 case statements which contain a C++ temporary variable.

A similar error occurs with the GreenHills C compiler, used on the
BBN Butterfly multicomputer.

A more serious problem occurs with picky compilers, such as the Meiko
Transputer C compiler, tc.  tc 'does it right' in it's scoping rules,
thus all variables within a new block are not visible outside of the block.
Apply this to a switch statement, and you get all case statements which
occur after a C++ temporary 'disappearing' from the containing switch
statement.  You can probably guess at the time it took to track this down.


The workaround for this problem is ALWAYS to  open a new block of your
own for each case statement, but this is hardly an ideal solution, and
not a great one to put in your user's manual...

Two questions:
    - Anybody know if this is fixed in AT&T 2.0?
    - Do other versions of C++ also exhibit this behaviour?

Any information available would be appreciated,

***** Larry Mellon <jsimellon@cpsc.ucalgary.ca>
***** Jade Simulations International (403) 282-5711


/******************* BUG EXAMPLE ********************/

typedef struct
{
    int         one;
    int         two;
} test;

test func();

main()
{
    int         i, j;

    i = 0;

    switch (i)
    {
    case 0:
			// a new block will be opened here for the temporary.
        j = func().one; // C++ will generate a temporary for this call.
	break;    
    case 1:
	j = 3;
	break;
    default:
	break;
    }			// and the block will be closed here.
}
test func()
{
    test x;

    x.one = 1;    x.two = 2;

    return x;
}
/******************* END OF C++ ****************/

And here we have the relevant C code generated.

switch (_au1_i )
{
case 0 :
{			/* Note the new block */
struct _C1 _au0__T2 ;

_au1_j = ( (_au0__T2 = func ( ) ), (& _au0__T2 )) -> __C1_one ;
break ;
case 1 :
_au1_j = 3 ;
break ;
default :
break ;
} }			/* And it's closing: after the switch statement */
}
};
/************* END OF C CODE **********************/