[comp.lang.c++] Stack overflow compiling y.tab.c

wmm@sdti.UUCP (William M. Miller) (09/30/87)

A couple of weeks ago, someone posted an article saying that they had
pretty much succesfully ported cfront, except that when they ran it on the
y.tab file it bombed with a stack overflow.  I posted a reply at that time,
but have only recently found out that our net feed was swallowing our
postings.  I am hence reposting the information; unfortunately I have lost
the original message and cannot give a reference.

I had the same experience when porting cfront to OS/2.  What I eventually
ended up doing was to split the huge switch statement in yyparse into
a bunch of 32-case pieces, i.e.,

	switch(yytmp) {
	case 1:
		...
	case 254:...
	}

became

	if (yytmp < 32) switch(yytmp) {
	case 1:
		...
	case 31:...
	} else if (yytmp < 64) switch(yytmp) {
	case 32:

etc.  It's not pretty, but at least it compiles without stack overflow now.
(I haven't any idea *why* large switch statements use up lots of stack space,
but they do.)
-- 
Non-disclaimer:  My boss and I always see eye-to-eye (every time I look in
the mirror).

...!genrad!mrst!sdti!wmm

werner@nikhefk.UUCP (Werner Vogels) (10/04/87)

In article <131@sdti.UUCP>, wmm@sdti.UUCP (William M. Miller) writes:
> 
> A couple of weeks ago, someone posted an article saying that they had
> pretty much succesfully ported cfront, except that when they ran it on the
> y.tab file it bombed with a stack overflow. 
> ......
> I had the same experience when porting cfront to OS/2.  What I eventually
> ended up doing was to split the huge switch statement in yyparse into
> a bunch of 32-case pieces, i.e.,
> 
> 	switch(yytmp) {
> 	case 1:
> 		...
> 	case 254:...
> 	}
> 
> became
> 
> 	if (yytmp < 32) switch(yytmp) {
> 	case 1:
> 		...
> 	case 31:...
> 	} else if (yytmp < 64) switch(yytmp) {
> 	case 32:
> 
> etc.  It's not pretty, but at least it compiles without stack overflow now.
> (I haven't any idea *why* large switch statements use up lots of stack space,
> but they do.)
> 

The article with the original problem was posted by me. The reason why it was
posted was because our system guru said that there was a default system stack
of .5 Mbyte and that the problems should be at scratch source level and not
due to systems limitations.

He was wrong...... .

Our loader (ld(1)) creates a default stack of 64 kBytes and this is not enough
for cfront to do y.tab.c succesfull. The functions evaluating the statements
(exp_eval, exp_del) are called in a heavily recursive way and thus use a lot of
stackspace with large switch statments.

The problems hould be solved by reloading the scratch translator with a bigger
stack (-m option). You should do some expiriments yourself to find a suitable
stacksize.

The K&R definition of the C language does not give a maximum number of labels 
in a switch statment, so neither is there for C++. You create a limited version
of the translator if you keep the stacksize small and limit yourself in the 
number of case labels. If the translator cannot handle the output of yacc,
something is wrong with your translator not with yacc.

I did not have time to thank all those who gave solutions to our problem by 
mail, so i like to thank you now for all your suggestions and help.


Werner H.P. Vogels

National Institute for Nuclear Physics and High-energy Physics
Section Nuclear Physics, Computer Systems Group.
postbus 4395 1009 AJ Amsterdam
The Netherlands
tel: +31 20 5922030
E-mail: ..!mcvax!nikhefk!werner (UUCP)