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