best way to return (char *)

Steve Summit scs at envy.pika.mit.edu
Sun Jul 2 07:32:03 AEST 1989


In article <7800013 at gistdev> joe at gistdev.UUCP lists several
common ways of implementing routines which return strings.
One technique I haven't seen mentioned is to implement a routine
which returns a pointer to not one, but to one of several static
areas.

A perfect example is a routine which generates a string
representation of an internal encoding, for use when generating
human-readable printouts.  For instance, in a C language
processor, an error must be generated when two types are
incompatible for a binary or casting operator.  I have used
code like the following:

	extern char *printtype(struct type *);
	extern void error(char *, ...);

	/* cast rhs to type of lhs, before assignment */

	if(rhs->type incompatible with lhs->type) {
		error("can't assign %s to %s", printtype(rhs->type),
							printtype(lhs->type));
		return ERROR;
	}

	cast(rhs, lhs->type);

	/* now do assignment... */

where printtype takes an internal structure describing a C type
and returns a string like "pointer to function returning int".
The code for printtype() looks something like

	#define NRETBUF 3
	#define MAXLEN 100

	char *
	printtype(type)
	struct type type;
	{
	static char retbufs[NRETBUF][MAXLEN];
	static int retbufi = 0;
	char *retbuf;

	retbuf = retbufs[retbufi];

	/* build descriptive string in retbuf */

	retbufi = (retbufi + 1) % NRETBUF;

	return retbuf;
	}

I agree with previous posters that general-purpose routines
should dynamically allocate the returned buffer, deallocation
difficulties notwithstanding.  For little special-purpose utility
routines, however, such as the output format helper above, any
handling of return buffer allocation by the caller would be
inconvenient (and might therefore make it less likely that good
error messages would be generated).  The multiple return buffer
trick is useful in these cases, since they are often the ones
(i.e. multiple calls within one printf) where the overwriting of
a single buffer would be a problem.  (Circumloqutions like

	error("can't assign %s ", printtype(rhs->type));
	error(" to %s", printtype(lhs->type));

are ugly, and don't work well if the error routine adds file or
line number information with each invocation.)

                                            Steve Summit
                                            scs at adam.pika.mit.edu



More information about the Comp.lang.c mailing list