A small bug about the c language

  • 2020-04-02 01:15:21
  • OfStack

Don't say more, said is a burden! Just look at the code!


<SPAN style="FONT-SIZE: 14px">#include <stdio.h>
int array[] = {23, 34, 12, 17, 204, 99, 16};
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))
int main (void)
{
    int d = -1, x;
    if( d <= (TOTAL_ELEMENTS -2))
    {   
        x = array[d+1];
        printf("d <= TOTAL_ELEMENTS-2n");
    }   
    else 
    {   
        printf("the bug is out!n");
    }   
    return 0;
}
</SPAN>

If you are interested, you can guess what the result is, and then run it to see if the result is the same as you think? What is the reason?

The following is the result of the line under GCC:

<SPAN style="FONT-SIZE: 14px">zy@pc:~/workspace/homework/commonfunc$ ./a.out 
the bug is out!
</SPAN>


<SPAN style="FONT-SIZE: 14px">
TOTAL_ELEMENTS </SPAN>

The value defined is of type unsigned int (because sizeof () returns an unsigned type), and the if statement tests for equality between signed and unsigned, so will

D upgrades to unsigned int, -1 converts to unsigned int, and the result is a very large positive integer, which makes the expression false.

So in order to get it right, you have to strongly transform it


<SPAN style="FONT-SIZE: 14px">if( d <=   (int)(TOTAL_ELEMENTS -2))
</SPAN>

So you get the right result!

Advice on unsigned;
1. Try not to use unsigned types in your code to avoid unnecessary complexity, especially if they are denoted simply because unsigned Numbers do not have negative values

2 try to use a signed type like int so that you don't have to worry about boundary cases when it comes to the complex details of upgrading mixed types (-1 translates to very large integers)

3 use unsigned Numbers only when using bit segments and binary masks. And you should use a cast in the expression so that the operands are signed or unsigned, so that the compiler does not have to choose the type of the result.


Related articles: