Is negating INT_MIN undefined behaviour?

前端 未结 3 565
别那么骄傲
别那么骄傲 2021-01-03 08:34

Let\'s say I have a variable i that comes from external sources:

int i = get_i();

Assuming i is INT_MIN

相关标签:
3条回答
  • 2021-01-03 09:11

    Is negating INT_MIN undefined behaviour?

    Yes, when INT_MIN < -INT_MAX - which is very common (2's complement). It is integer overflow.

    int i = get_i();
    
    #if INT_MIN < -INT_MAX
    if (i == INT_MIN) {
      fprintf(stderr, "Houston, we have a problem\n");
      // Maybe return or exit here.
    }
    #endif 
    
    int j = -i;
    

    Houston, we have a problem

    0 讨论(0)
  • 2021-01-03 09:13

    Platforms may choose to define the behavior, but the C Standard does not require that they guarantee anything about it. While historically microcomputer compilers have relatively consistently behaved as though -INT_MIN would yield INT_MIN or in some cases a number that behaves like a value one larger than INT_MAX, it has become more fashionable to instead have it retroactively change the value of whatever was being negated. Thus, given:

    int wowzers(int x)
    {
      if (x != INT_MIN) printf("Not int min!");
      return -x;
    }
    

    a hyper-modern compiler may use the expression -x to determine that x can't have been equal to INT_MIN when the previous comparison was performed, and may thus perform the printf unconditionally.

    Incidentally, gcc 8.2 will use the UB-ness of negating INT_MIN to "optimize" the following

    int qq,rr;
    void test(unsigned short q)
    {
        for (int i=0; i<=q; i++)
        {
            qq=-2147483647-i;
            rr=qq;
            rr=-rr;
        }
    }
    

    into code that unconditionally stores -2147483647 to qq and 2147483647 to rr. Removing the rr=-rr line will make the code store -2147483647 or -2147483648 into both qq and rr, depending upon whether q is zero.

    0 讨论(0)
  • 2021-01-03 09:14

    It depends on the platform. C supports three representations for negative numbers (see section 6.2.6.2 of the C99 standard):

    • Two's complement.
    • One's complement.
    • Sign and magnitude.

    With one's complement and sign and magnitude, -INT_MIN is defined (and equal to INT_MAX). With two's complement, it depends on whether the value with sign bit 1 and all value bits zero is a trap representation or a normal value. If it's a normal value, -INT_MIN overflows, resulting in undefined behavior (see section 6.5 of the C99 standard). If it's a trap representation, -INT_MIN equals INT_MAX.

    That said, most modern platforms use two's complement without trap representations, so -INT_MIN typically results in undefined behavior.

    0 讨论(0)
提交回复
热议问题