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

    +144

    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
    #include <stdio.h>
    
    // Говнокод здесь
    #define ABS(x) ((x) ? (x) : (-(x)))
    
    int main () {
    	char ch = -128;
    	short sm = -32768;
    	int i = -2147483647; i--;                                    // здесь
    	long long l = -9223372036854775807LL; l--; // и здесь декременты нужны
    	                                                                             // для подавления варнингов
    	
    	printf("char:\t\tABS(%hhd) = %hhd\n", ch, ABS(ch));
    	printf("short:\t\tABS(%hd) = %hd\n", sh, ABS(sh));
    	printf("int:\t\tABS(%d) = %d\n", i, ABS(i));
    	printf("long long:\tABS(%lld) = %lld\n", l, ABS(l));
    
    	return 0;
    }

    Может быть, баян, но...
    Всем знакомый макрос ABS способен сделать большую гадость.
    Вот вывод программы:
    char: ABS(-128) = -128
    short: ABS(-32768) = -32768
    int: ABS(-2147483648) = -2147483648
    long long: ABS(-9223372036854775808) = -9223372036854775808

    Запостил: whiskey, 12 Ноября 2010

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

    • Извините, что табы уползли в комментах.
      Ответить
    • > #define ABS(x) ((x) ? (x) : (-(x)))

      Чего-то я не понял, но это ни какой не abs
      Ответить
      • Да, вероятно имелось в виду #define ABS(x) ((x>0) ? (x) : (-(x)))

        Но действительно есть такая фишка, что для minValue нет противоположного положительного значения, т.к. числа кодируются несимметрично.

        Ну и в разных языках в этом случае происходят разные забавные вещи.

        Мораль: нефиг считать на грани диапазонов.
        Ответить
      • показать все, что скрытоЕщё какой abs. Эта конструкция используется в куче прог и библиотек.
        Ответить
        • То, что указано у вас в 4ой строке дает обычное повторение значения.
          Для целых типов по крайней мере.
          Ответить
    • Я, в принципе, ожидал, что заминусуют. Код, действительно, не очень тянет на говнокод. Просто хотел лишний раз обратить внимание на то, как простое решение может породить сложную проблему.
      Ответить
      • Чему должны быть равны соответствующие значения при правильном, а не простом решении?
        char: ABS(-128) = ?
        short: ABS(-32768) = ?
        int: ABS(-2147483648) = ?
        long long: ABS(-9223372036854775808) = ?
        Ответить
        • 2sectus
          +1.

          я вот только что доказывал другу что в .NETe говна хватает и вспомнил винрарнейший говнокод 3117
          Ответить
    • Чем не нравится стандартный abs из stdlib.h? А за переполнениями программист должен следить сам
      Ответить
    • ну что поделаешь, если кол-во отрицательных и положительных чисел, кодируемых конечным числом байт -- не равно. не вводить же два ноля?)
      Ответить
      • Ввести "минус ноль". abs(-0) = 0, (-0) x (-0) = 0, и всё в том же духе.
        Ответить
        • >Ввести "минус ноль"
          А потом париться со сравнением +0 и -0.
          Ответить
          • Пора вводить тег "ирония". Чуть тоньше, чем "лопата", и не катит уже.
            Ответить
        • кстати, вот вам http://govnokod.ru/4604#comment52552
          Ответить
    • надо бы кастить результат в unsigned
      Ответить
      • и получать нежданчик на выходе?
        замечательно!
        Ответить

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