rbutterworth@watmath.UUCP (Ray Butterworth) (10/17/86)
How many programs now rely on "while (isdigit(d=*++ptr)) ...", or "while (isdigit(d=getchar())) ..." ? Probably a lot, since these nearly always work correctly. The X3J11 committee seems to have tried to make such things reliable and portable, but they only went half way there. ANSI X3J11 4.3 <ctype.h>: ... In all cases the argument is an int, the value of which shall be representable as an unsigned char or shall equal the value of the macro EOF. If the argument has any other value, the behaviour is undefined. This doubles the size of the ctype table from 129 to 257 bytes, but at least it fixes one problem with the current <ctype.h> that blows up if getchar() returns a character with the upper bit on. e.g. if the input stream contains '\234', getchar() returns the int 0234, and isdigit(0234) is sometimes true, sometimes false, and possibly sometimes a machine fault. But if they are going the solve the problem of isdigit(getchar()), why couldn't they have added another 128 bytes and solved the similar problem of isdigit(*string)? If *string contains '\234', *string may be evaluated as -0144, and isdigit(*string) will still be unreliable. As it is, the only portable version of this requires something like "while (isdigit(d=*(unsigned char*)++ptr)) ...". This might be portable, but it sure is ugly, especially when one considers that isdigit() is defined as an X3J11 portable C function. I can't imagine many people putting stuff like this into their code (at least not until they actually run into the problem). It is unfortunate that X3J11 didn't either fix their definition to be truely portable or at least leave these things in the mess that they already are. If I'm misreading their definition, and they really do want both getchar() and *(char*)ptr to be valid arguments, perhaps they could make this more explicit. P.S. (I know that the number 128 and even the existence of the table are implementation specific.)