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 **********************/