(Why) is using an uninitialized variable undefined behavior?

后端 未结 7 2388
暗喜
暗喜 2020-11-21 05:01

If I have:

unsigned int x;
x -= x;

it\'s clear that x should be zero after this expression, but everywhere I look, th

7条回答
  •  旧时难觅i
    2020-11-21 05:24

    While many answers focus on processors that trap on uninitialized-register access, quirky behaviors can arise even on platforms which have no such traps, using compilers that make no particular effort to exploit UB. Consider the code:

    volatile uint32_t a,b;
    uin16_t moo(uint32_t x, uint16_t y, uint32_t z)
    {
      uint16_t temp;
      if (a)
        temp = y;
      else if (b)
        temp = z;
      return temp;  
    }
    

    a compiler for a platform like the ARM where all instructions other than loads and stores operate on 32-bit registers might reasonably process the code in a fashion equivalent to:

    volatile uint32_t a,b;
    // Note: y is known to be 0..65535
    // x, y, and z are received in 32-bit registers r0, r1, r2
    uin32_t moo(uint32_t x, uint32_t y, uint32_t z)
    {
      // Since x is never used past this point, and since the return value
      // will need to be in r0, a compiler could map temp to r0
      uint32_t temp;
      if (a)
        temp = y;
      else if (b)
        temp = z & 0xFFFF;
      return temp;  
    }
    

    If either volatile reads yield a non-zero value, r0 will get loaded with a value in the range 0...65535. Otherwise it will yield whatever it held when the function was called (i.e. the value passed into x), which might not be a value in the range 0..65535. The Standard lacks any terminology to describe the behavior of value whose type is uint16_t but whose value is outside the range of 0..65535, except to say that any action which could produce such behavior invokes UB.

提交回复
热议问题