[comp.lang.c] "Correct" toupper

garys@clunker.UUCP (Gary M. Samuelson) (06/09/87)

In article <494@ucsbcsl.UUCP> lombrozo@ucsbcsl.UUCP (Peter Lombrozo) writes:
>I don't suppose anyone noticed the correct #define for toupper() is:
>
>#define toupper(c)  ( (islower(c)) ? _toupper(c) : (c) )
>???
>			lombrozo@cslvax

Well, that is MSC's definition, but, if I recall correctly, the
original issue was the fact that the argument is evaluated twice.

I'm not sure what you mean by calling the above definition "correct" --
is it listed in K & R or the proposed ANSI standard?  (I didn't find it
defined in K & R, and don't have the ANSI document handy.)

The definition that comes with Berkeley 4.1 is:

	#define toupper(c)	((c)-'a'+'A')

On our Altos's, with SYS V, the above is the definition of _toupper (note
leading underscore), and 'toupper' is not defined.

If you want a macro which evaluates its argument only once, set up a
translation table:

	unsigned char tran_to_upper[ 256 ] =
	{	0x00, 0x01, 0x02, 0x03 ...

etc., where tran_to_upper[i] == i except where i represents a lower case
letter.  Then define toupper as follows:

	#define toupper(c)	(tran_to_upper[ (c) & 0xff ])

Now toupper is fast, evaluates its argument only once, and leaves
non-letters unchanged, at the cost of a 256 byte table linked in with
your other libraries, which isn't much.  Besides, you no longer have
the toupper function, so if the macro is used frequently enough, and/or
function calls are expensive enough, you might even save memory.

Gary Samuelson