strcpy wars, jeez! A proposed resolution.

Richard A. O'Keefe ok at quintus.UUCP
Fri Apr 8 17:21:41 AEST 1988


In article <17 at feedme.UUCP>, doug at feedme.UUCP (Doug Salot) writes:
> Both of these passages seem to imply that C compilers "know" about
> the semantics of certain (all?) function calls.  While someone earlier
> pointed out that it is possible to design a language in which some semantics 
> can be described, C does not have this facility and seems to be
> philosphically antagonistic to such a facility.  I would indeed be
> surprised if a C compiler produced inline code for strcpy ...

strcpy() is defined as part of the dpANS.  X3J11 has gone to a great
deal of trouble to ensure that a useful chunk of the C library will be
present.  One way of looking at it is to think of things like strcpy()
as built-in operations which merely happen to use functional notation.
[This isn't 100% accurate; but it is the basic idea.]  So an ANSI C
compiler *will* be entitled to "know" about the semantics of "functions"
which are defined in the standard, just as a Pascal compiler is entitled
to "know" about sqrt(). Indeed, it simply is not possible for a user to
define a function called strcpy() in a standard- conforming way, because
names beginning with "str" are reserved.

The argument is over what strcpy(dst, src) should mean when
	src <= dst <= src+strlen(src)+1.

There are two basic positions:
(A)	Strict left-to-right copy is easy to understand and is often
	useful.  It is also how many C books (including K&R) have
	explained the operation, so many C programmers expect this
	behaviour.

(B)	The implementor should be given as much freedom as possible
	in order to make this operation supremely fast, and if this
	means leaving the operation as unspecified as possible, sobeit.

Note that if you have been using a system where the implementor had
already taken attitude (B), and you move a working program to a system
whose implementor took attitude (A), your code will continue to work,
but if you move code in the other direction your code is likely to break.

Requiring strict left-to-right copying in the standard will therefore
improve future portability and maintainability, at the expense of
prohibiting certain machine-specific optimisations in this particular
operation.

May I respectfully suggest that the emphasis on the implementor's
freedom to optimise strcpy() may, just possibly, be misguided?  I have
done text manipulation in a wide variety of programming languages, and
have found C to be easily the nicest of them, because user-defined
operations (compare this padded string to this NUL-terminated string,
for example) are not an order of magnitude slower than built-ins (such
as strcmp()).  If compiler-writers have N man-months to spend improving
their compiler, I would much rather they spent them on optimisations
that will affect code that I write rather than builtins which seldom do
exactly what I want.  {If they are going to optimise a builtin, let it
be sprintf(), please.}  It is especially misguided to spend those N
man-months on optimising an operation which, in order to permit such
optimisation, has been left so vaguely defined that I can't trust it!

As a matter of interest, just how important is the speed of strcpy()
in practice, anyway?  If the cost of strcpy() were reduced to zero,
would your programs go 1% faster, 2% faster, or what?  In an attempt
to get some sort of feeling for this, I used the Sun C compiler's
".il" (inline) facility to compare the existing library routines with
my own C code and with in-lined unrolled hand-tuned assembly code.

	Library		My C code	In-line assembler (unrolled)
strlen	1.0		1.22		0.26	(~ 4 times faster)
strcpy	1.0		1.06		0.87	(~ 13% faster)
strcmp	1.0		1.00		0.82	(~ 18% faster)

To be fair to Sun, it should be noted that I was using an old compiler
and library; the 4.0 compiler is supposed to be rather better.  But
this means that if I had used a newer Sun compiler, the C code would
have looked better, and the assembler code would not have changed.

Note that the in-lined versions eliminated the procedure calling
overhead entirely.  It is also worth noting that it costs nearly as
much to find the length of a string as to move it:  on this particular
machine, given the choice of calling an optimised strlen() and an
optimised memmove() {==bcopy()} or calling your own C code, you would
be a fool not to use your own C code.  What price "optimisation"?

Could someone give us some figures for the 4.3 strcpy() using locc
{I can't do this, because our microVAX hasn't got a locc instruction}
and movc3, comparing them with similarly tuned code not using locc
and with code produced by a good C compiler?

A lot of C programmers use 80*86s.  What about them?  Well, strict
left-to-right copying has the advantage of not having to fiddle with
the direction flag...

So I guess the question is whether the importance of strcpy is
(A)	as a standard operation you thoroughly understand, or

(B)	as a vaguely defined operation which the vendor was allowed
	to tune to make his Dhrystone results look good.



More information about the Comp.lang.c mailing list