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

    +108.6

    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
    /**
     * Копирует первое большое число во второе.
     *
     * @param a большое число приемник
     * @param b большое число источник
     * @param n длинна больших чисел в словах
     *
     * @return FALSE - четное, TRUE - нечетное
     */
    void int_copy(uword_t *a, const uword_t *b, const int n)
    {
        memcpy(a, b, sizeof(a[0]) * n);
    }

    Вот такую милую функцию я нашел в проекте над которым работаю.

    Запостил: pvkr2, 12 Октября 2009

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

    • gg!
      Ответить
    • ну и чо? может оно аццки большое :)
      Ответить
    • Особенно радует return в комментарии
      Ответить
    • > длинна
      ДОКОЛЕ!? Сколько можно это слово с двумя 'н' писать?
      Ответить
    • memset и memcpy, конечно, источник проблем... в объектно ориентированных языках. Для Си же, по-моему, их использование не только оправдано, но и является наиболее простым средством работы с массивами. Это же не C++, где легко перегружается operator= и конструктор.
      Что же касается других аспектов кода: конечно, не хватает проверок и по моему мнению комментарии - это зло. Особенно как в приведенном фрагменте. Код не должен требовать комментариев для того, чтобы его можно было прочесть. Отсюда и забытый return в шапке функции. Почему не писать так:
      void copy(uword_t* destination, const uword_t* source, const int elements_count)
      {
      ASSERT(destination!=NULL);
      ASSERT(source!=NULL);
      memcpy(destination, source, sizeof(destination[0]) * elements_count);
      }
      Достаточно того, что приходится поддерживать код. Не заставляйте людей поддерживать еще и комментарии.
      Ответить
      • Зачем вообще писать такую функцию, с такими названиями?
        А если сущности будут не elements_count, а elliptic_curve_over_galois_field_gf2m_ct x к примеру?
        ASSERT тоже темный)
        Ответить
        • > Зачем вообще писать такую функцию, с такими названиями?
          Вероятно, не понял вопроса. А зачем вообще пишутся функции? Что не устраивает в названиях?
          Пример:
          typedef struct
          {
          unsigned int low;
          unsigned int high;
          } uword_t;
          uword_t* some_data, some_another_data;
          ...
          copy(some_data, some_another_data);

          > А если сущности будут не elements_count, а elliptic_curve_over_galois_field_gf2m_ct x к примеру?
          значит пора выспаться :-)
          Такие сущности исчезают при декомпозиции кода. Тип объекта (структуры, сущности) не нужно указывать в имени.

          > ASSERT тоже темный)
          дык, а каким ему быть? Тут многое зависит от проекта, платформы и режимов тестирования. Я обычно пишу макрос наиболее подходящий для проекта. Суть в том, что проверка должна быть
          Ответить
          • Ты херню поришь. Столь постая функция memcpy(3) не должна требовать оберток. Лечись!
            Ответить
          • > Зачем вообще писать такую функцию, с такими названиями?
            Я к тому что можно использовать memcpy вместо int_copy, последняя ничего нового не привносит.
            > А если сущности будут не elements_count, а elliptic_curve_over_galois_field_gf2m_ct x к примеру?
            Это я к тому что переменные можно и покороче называть (elements_count -> n,len,cnt,count,size).
            >ASSERT тоже темный)
            Это я к тому что вы не проверяете на (void*)1, (void*)2,..., ИМХО пригодилось бы:)
            Ответить
            • > Я к тому что можно использовать memcpy вместо int_copy, последняя ничего нового не привносит.
              Кроме одного маленького отличия: строгой типизации аргументов. То есть небольшую часть работы по проверке ошибок автор переложил на компилятор. Это плюс.

              > Это я к тому что переменные можно и покороче называть
              Можно. По русски тоже можно писать и говорить сокращениями.
              "Краткость с. т."
              Вопрос зачем. Компилятор не понимает длинных имен?
              Вот, например, можно назвать сущность elliptic_curve_over_galois_field_gf2m_ct _x
              x
              Это сделает код более читаемым? ИМХО косметика над говнокодом. Такие сущности просто не должны появляться. А говнокод - должен выглядеть говнокодом. Это просто :-)
              Ответить
              • 1) Полностью согласен по поводу типизации. Это плюс.
                2) Думаю мы расфлудились,
                - я за краткость, но в разумной степени;
                - я за комментарии - это сугубо моё мнение и никому его не навязываю, главное чтобы код был читабельным.
                Ответить
                • Согласен. Спасибо за интересное обсуждение.
                  Ответить
      • Нахрена нужны проверки указателя на NULL? У тебя все равно там выскочит рантайм еррор, по которому узнаешь место ошибки.
        Вот лучше сделать проверку на то, чтобы интервалы в памяти не пересекались.
        Ответить
        • Проверка на интервалы - вещь однозначно хорошая. Я бы добавил.
          > Нахрена нужны проверки указателя на NULL?
          например так: copy(some_data, NULL, 0);
          Думаешь так сойдет? ;-)
          Да и в релизе можно придумать поведение логичней рантайм еррора )
          Ответить
          • В релизе обычно от асерта ничего не остается.
            Чтение/запись по нулевому адресу в дебаге всегда отлавливается средой.
            Ответить
        • В С99 для memcpy аргументы содержат restrict квалификатор.
          Ответить
    • Вот читаю и думаю, кто-нибудь сможет ответить зачем:
      1) const int size;
      2) sizeof(a[0]) если тип данных фиксированный;
      3) да и вообще зачем такая функция?

      А то умничают тут по поводу проверок и т.п., может вам еще проверять температуру тела при компиляции кода? Ведь если повышенная, то вероятность ошибочности вашего кода велика О_О
      Ответить
      • Может вам еще нужны функции по типу:
        bool is_true (bool a)
        {
        if (a)
        return true;
        else
        return false;
        }

        Так, вдруг пригодится...
        Ответить
        • :)
          Ответить
        • Да. Нужны. Неверишь? Спроси у первого встречного.
          Ответить
        • Судя по названию проверяет правдивость содержимого переменной. Иногда такое действительно нужно. Каким алгоритмом это делать мы обсуждать не будем. Конечно врятли выше приведенным. Но кто знает. Может где-то, как временный кастыль в недоделанном коде - сойдёт.
          Ответить
          • Действительно. Вдруг если a=true, то это известно доподлинно.
            А если a=false, то с некоторой вероятностью =false, а может =true. Кто знает. Пути программистов неисповедимы...
            Ответить
            • Если кинуть монету и выпадет орел, то это орел, а если решка, то с небольшой вероятностью это может оказаться орел? О_О
              Ответить
              • Да. Ещё может встать на ребро. А ещё зависнуть в воздухе.
                Ответить
          • Как костыль чего? Мозга?
            Кто будет использовать такую функцию и для чего?
            Если это написано на полном серьезе, то вы явно не на тот сайт зашли.
            Ответить
          • Аха, только вызов функции - отнимает время. Делать функцию из одной функции - это изначально бред. Надо либо добавлять слово inline, либо делать макросом. Притом второе делает код менее красивым.
            Ответить
            • Это относится к функции автора... да и к приведённой тут для сарказма функции тоже.
              Ответить
    • ОНОТОЛЕ одобряе.
      Ответить
    • JAVADOC детектед!
      Ответить
    • Быдлокода здесь нет.
      Для хранения длинных чисел, вероятно, используются массивы, поэтому куда быстрее скопировать участок памяти, чем в цикле копировать отдельные цифры.
      Хотя, блядь, ещё быстрее (и намного быстрее) было бы поменять указатели массивов.
      Ответить
      • >> Хотя, блядь, ещё быстрее (и намного быстрее) было бы поменять указатели массивов.
        говнокодер детектед :D
        Ответить

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