Am 10.08.2011 13:24, schrieb Harald Becker: > Hallo Denys! > >> On Tue, Aug 9, 2011 at 7:33 PM, Rich Felker <[email protected]> wrote: >>> On Tue, Aug 09, 2011 at 09:37:58AM +0200, Denys Vlasenko wrote: >>>> #define isalnum(a) bb_ascii_isalnum(a) >>>> static ALWAYS_INLINE int bb_ascii_isalnum(unsigned char a) >>>> { >>>> unsigned char b = a - '0'; >>>> if (b <= 9) >>>> return (b <= 9); >>>> b = (a|0x20) - 'a'; >>>> return b <= 'z' - 'a'; >>>> } >>> I'm scared to ask why this is written in such an obfuscated way rather >>> than just >>> >>> return a-'0'<10U || (a|32)-'a'<26U; >> Tried it. Bloatcheck: >> [...] > > FYI: I tried it too ... test this version: > > return (unsigned char)(a-'0')<10U || (unsigned char)((a|32)-'a')<26U; > > ... may look obscure, but influences the way gcc produces code! May be > you need to fiddle with type casting the other arguments in the > expression :-(
Nothing in that is obscure, the answer is in the "integral promotion" rules of C which is what required the extension from unsigned char to unsigned int, hence the movz* commands in Denys's sample. It pays to read the C and Unix standard, and you'll figure that the simpler version causes implicit promotion to "unsigned int" - and note that the C standard ctype.h signature demands "int interpreted as unsigned char, or EOF". This sidesteps lots of the problems observed here because no conversion happens inside the forcibly inlined bb_ascii_alnum... _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
