[comp.lang.c++] AT&T 2.1 and stdargs

gas@cs.nott.ac.uk (Alan Shepherd) (09/19/90)

I've just installed AT&T 2.1 on a sparc station 1 running sunos4.1 and
I'm having real trouble with stdargs.  The code for the routine is
below:

void as_log(char* message1, ...)
{
    aslog.open(logfile.chars(),ios::app);
    if (!aslog.good())
        return;
    va_list ap;
    va_start(ap, message1);
    aslog << message1 << " ";
    char* ptr = va_arg(ap,char*);
    while ((ptr) && (*ptr != NULL)) {
        aslog << ptr;
        ptr = va_arg(ap,char*);
    }
    va_end(ap);
    aslog << endl;
}

The problem is that for no apparent reason and at varying times, the
parameters to as_log get confused.  The first parameter (message1) is
always fine, but the rest sometimes become garbage.  I've run it
through a debugger and the values in the calling routine are still
fine.  Has anyone else experienced this problem ?  Is there something
wrong with my code ?  (It worked with 2.0).

Another issue:  cfront 2.1 seems to use up an awful lot of memory
(8M!) whilst executing.  Is this normal ?  I often have to kick
everybody off the machine so I can compile avoiding memory errors !

Alan Shepherd

grahamd@otc.otca.oz.au (Graham Dumpleton) (09/21/90)

In article <1990Sep19.062219.29519@cs.nott.ac.uk>, gas@cs.nott.ac.uk
(Alan Shepherd) writes:
|> 
|> I've just installed AT&T 2.1 on a sparc station 1 running sunos4.1 and
|> I'm having real trouble with stdargs.  The code for the routine is
|> below:
|> 
|> ...

This problem was discussed back in Dec 89. I've used this and it works fine.
Note that if you have source then you should also modify the file
oldformat.c in lib/stream and fix the function form() which uses varargs
and then recompile libC.a.

Article 5244 of comp.lang.c++
Path:
otc!metro!basser!munnari.oz.au!samsung!cs.utexas.edu!uunet!tut.cis.ohio-
-state.edu!ucbvax!bloom-beacon!eru!luth!sunic!mcsun!ukc!warwick!steve
From: steve@maths.warwick.ac.uk (Steve Rumsby)
Newsgroups: comp.lang.c++
Subject: Re: stdarg on sparc
Message-ID: <2030@diamond.warwick.ac.uk>
Date: 12 Dec 89 16:33:42 GMT
Sender: news@warwick.ac.uk
Reply-To: steve@maths.warwick.ac.uk (Steve Rumsby)
Organization: Mathematics Institute, University of Warwick, UK.
Lines: 91


Yes, it's possible to make it work. There are two things you need to do,
one to the code itself, and one to the CC script (or to the output of
CC -Fc before feeding to cc itself if you can't hack CC).

1) To the code using stdargs:

First, add this to the beginning, or in a header file that you include,
or somewhere:

#ifdef	sparc
#define	SA(x)	__builtin_va_alist
#else
#define	SA(x)	x
#endif

Then change code like this:

void
foo(int x, char *p, ...)
{
	va_list ap;

	if(!p)
		return;

	va_start(ap, p);

	[...etc...]
}

To this:

void
foo(int x, char *SA(p), ...)
{
	va_list ap;

	if(!SA(p))
		return;

	va_start(ap, SA(p));

	[...etc...]
}

ie. change ALL occurances of the last named argument to SA(name).

2) Changes to CC itself:
   Cfront in going to mangle the __builtin_va_alist parameter name, so
   we need to unmangle it again so that the C compiler gets to see it.
   Do this to the output of cfront:

	sed -e 's/__0__builtin_va_alist/__builtin_va_alist/g'

   You can either do this in the CC script by changing all occurances of
   "cfront" to "cfront | sed", or you can do it to the output of CC -Fc
   and feed it to cc manually. This sed script can obviously be generalised
   to unmangle a larger set of identifiers (like all __builtin ones) if
   necessary (eg. to use gcc instead of cc as the C compiler).

Voila! You now have stdargs working on a sparc machine.

Note that there is a slightly more complex usage of stdargs in C++ which
breaks the above system. This is where arguments after the last named one
have default values, like so:

extern void foo(int, char *, int = 2, ...);

void
foo(int x, char *p, int, ...)
{
	va_list ap;

	va_start(ap, p);
}

[Is this legal? I found it in ET++]

Cfront will make up names for the unnamed arguments, and the Sun C compiler
complains about arguments after __builtin_va_alist. To make this work you
need to rip out these extra arguments (I don't understand why cfront puts them
there in the first place, actually). This is somewhat more difficult, but
not impossible. I haven't got around to fixing this yet...

					Hope all this helps,
					  Steve.


UUCP:	 ...!ukc!warwick!steve		Internet: steve@maths.warwick.ac.uk
JANET:	 steve@uk.ac.warwick.maths	PHONE:	 +44 203 523523 x2657





Graham Dumpleton (grahamd@otc.oz.au)

warren@cbnewsh.att.com (warren.a.montgomery) (09/23/90)

My work group spent quite a bit of time tracking down problems
with the use of stdargs on a Sparc based machine.  We concluded
that you cannot compile code that uses stdargs with the optimizer
on a Sparc based Sun.  The trouble appears to be that the optizer
uses the name of the arguments to a function to deterine whether
or not the function may take varying arguments, and if so whether
it needs to be compiled so as to preserve the argument stack for
use by the varargs or stdargs library.  The C++ name mangling
procedure does not always produce the right "magic" parameter name
to trigger the generation of the varying arguments code, and
the call will fail if it isn't generated correctly.  I believe
that the optimization only has to be disabled on the compilation
of the varying arguments function itself, not the things that call
it.

-- 

	Warren Montgomery
	att!ihlpf!warren