Search code examples
cbitwise-operatorsmask

What is difference between calling isdigit(c) and isdigit(c&0xFF). Masking the isdigit "&0xFF"


The function isdigit can be called with a character but if we send an and bit "&" with the 255 decimal number why we do that. I have found this from a sample example in c

      const char *value =1234567890abcdefghijklm";
     for(i=0; value[i]; i++)  {
      int r1 = isdigit(value[i]);
      int r2 = isdigit(value[i]&0xFF);
      printf("%d %d\n", r1,r2);

if I output the above I can not see the difference between r1 and r2

2048 2048
2048 2048
2048 2048
2048 2048
2048 2048
2048 2048
2048 2048
2048 2048
2048 2048
2048 2048
0 0
0 0
0 0
0 0
0 0
0 0
0 0

0 0 0 0 0 0 0 0 0 0 0 0

why masking the value by 255 (1byte)?


Solution

  • The argument to isdigit is of type int, and must be either equal to EOF (typically -1) or in the representable range of unsigned char.

    If plain char is signed, then it can hold negative values, and passing a negative value other than EOF to isdigit has undefined behavior. That means that passing an element of a string to isdigit is unsafe.

    The usual way to avoid this problem is to convert the argument to unsigned char:

    int r2 = isdigit((unsigned char)value[i]);
    

    and in fact I recommend doing it that way.

    Doing a bitwise and with 0xff probably has the same effect, though there may be some subtle differences involving integer promotions and applying bitwise operations to signed types (which I'm too lazy to figure out).

    The purpose of doing a bitwise and with 0xff is to avoid undefined behavior when calling isdigit. But converting to unsigned char is a bit cleaner.