1. C++ / Говнокод #16942

    +52

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    #include <iostream>
    using namespace std;
    
    void foo()
    {
        int i = 0xffffffff;
        cout << i << endl;
    }
    
    void bar()
    {
        bool b;
    	if(b)
    	{
    		cout << "true" << endl;
    	}
    	if(!b)
    	{
    		cout << "false" << endl;
    	}
    }
    
    int main()
    {
        foo();
        bar();
    	return 0;
    }

    http://rextester.com/HJRO12041

    Запостил: DlangGovno, 26 Октября 2014

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

    • Fixed: http://codepad.org/LJL07X7s
      Ответить
    • Сужение если целевая переменная — знаковая = UB. В данном случае просто записали побитовое представление.

      Использование неинициализированной переменной = UB. ГЦЦ использует xor 1 чтобы обратить значение, т.к. не ожидает что там будет что-то кроме 0 или 1. Поэтому если там что-то другое получим один и тот же результат когда будем сравнивать с нулём.

      Компилятор ругается на оба случая, как бэ говоря "Не делай этого".
      Кто сделал — ССЗБ.

      За пример — спасибо, я вчера полчаса угробил пытаясь заставить бул себя так вести.
      Ответить
      • > Сужение если целевая переменная — знаковая = UB. В данном случае просто записали побитовое представление.
        Это о чём вообще?

        > Использование неинициализированной переменной = UB.
        Ага.

        > ГЦЦ использует xor 1 чтобы обратить значение, т.к. не ожидает что там будет что-то кроме 0 или 1.
        А у этого какие-то подтверждения есть? Кстати, мой вариант кода эту версию не подтверждает.
        У меня подозрения, что он просто выпиливает проверку, поскольку значение неопределённое.
        Ответить
        • Он прав насчет xor, но воспроизводится только если компилять без оптимизации, проверить можно здесь: http://gcc.godbolt.org/
          int i = 0xffffffff нужен только чтобы на стеке мусор остался, иначе там будут нули.
          Ответить
          • > проверить можно здесь: http://gcc.godbolt.org/
            Не проверяется:
            <No output: Error: stdout maxBuffer exceeded.>

            > Он прав насчет xor
            Почему тогда в моём варианте только true?
            Ответить
            • > Не проверяется
              Там можно посмотреть асмовыхлоп

              > Почему тогда в моём варианте только true?
              Потому что зависит от компилятора и флагов
              Ответить
            • > Почему тогда в моём варианте только true?
              Потому что UB.
              Ответить
        • Литерал 0xffffffff имеет тип unsigned int. (по 2.14.2.2 The type of an integer literal is the first of the corresponding list in Table 6 in which its value can be represented.).
          Запихнуть его в простой инт не выходит, так что результат implementation defined, не UB, я ошибся. (4.7.3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.)
          В данном случае "лишний" бит записали заместо знакового. Если бы этот бит был бы нулевым:
          int i = 0xf'7fff'ffff;
          То получим INT_MAX (на конкретном компиляторе, implementation defined же)
          Ответить
    • показать все, что скрыто-
      Ответить
    • хуйня
      Ответить

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