1. Си / Говнокод #23143

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    #include <stdio.h>;
    
    void check(int x, int y) {
      if (2*x == y && y < 0 && 0 <= 2*x) {
        puts("Impossible!");
      }
    }
    
    int main() {
      check(0x7F80007F, 0xFF0000FE);
    }

    https://runtimeverification.com/blog/?p=257
    When writing code for a specific compiler you can rely on the implementation-specified behavior, but signed overflow is still problematic. GCC promises that conversions between integer types will be reduced modulo the appropriate power of two when the value is not representable in the target type. This means that with GCC the conversion above will initialize var to -0x112234 on any architecture that GCC supports. However, only initialization and other conversions are safe. GCC still considers signed overflow in arithmetic as undefined behavior, and optimizes under the assumption that there will be no overflow. This can lead to apparently impossible results when signed values do overflow. Compiled with -O3, this program prints “Impossible!”.

    By adding apparently-redundant casts to 2*x to give (int)(2*(unsigned int)x), the calculation becomes implementation-specified behavior from an out-of-range conversion instead of undefined behavior. While this code may not be portable between compilers, GCC now guarantees the “impossible” code will not be executed even with -O3.

    Запостил: j123123, 20 Июня 2017

    Комментарии (2) RSS

    • не все поймут суть этого говна
      Ответить
    • Есть пример намного проще
      int f(int x) {
        if (x * 8 == 0) return 123;
        return x * 8;
      }
      int main() {
        if (f(1<<30) == 0) printf("Impossible\n");
      }
      Ответить

    Добавить комментарий