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

    +53

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    //
    // 'compare_keywords()' - Compare two keywords...
    //
    
    extern "C" {
      int
      compare_keywords(const void *a,
                       const void *b) {
        return (strcmp(*((const char **)a), *((const char **)b)));
      }
    }

    Запостил: govnokod3r, 04 Декабря 2014

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

    • Инкапсуляция же! Ну если, конечно, там есть всякие create_keyword(), free_keyword() и т.п.

      P.S. Но каст ужасен.
      Ответить
    • Блин, сразу не увидел, оно с bsearch используется. Так, что наверное не говно.

      Хотя, вроде можно и strcmp напрямую засунуть
      http://www.cplusplus.com/reference/cstdlib/bsearch/
      bsearch (key, strvalues, 4, 20, (int(*)(const void*,const void*)) strcmp);
      Ответить
      • Хм, а нафиг тогда extern c, если эта функция не для экспорта?

        З.Ы. Претензии к касту сняты.
        Ответить
        • > З.Ы. Претензии к касту сняты
          Честно говоря, reinterpet_cast выглядел бы няшнее тут (ведь C++ же!):
          return strcmp(*reinterpret_cast<const char**>(a), 
                        *reinterpret_cast<const char**>(b));
          Ответить
          • > reinterpret
            а static не прокатит?
            Ответить
            • UPD: прокатывает. Только тип должен быть не const char **.
              return strcmp(
                  *static_cast<const char * const *>(a),
                  *static_cast<const char * const *>(b));
              Заодно компилятор мне поведал, что каст нехороший - он отбрасывает const квалификатор от const void *. Ибо после каста указатель уже не константный получается. Но это всё мелочи.
              Ответить
      • Хотя, вроде можно и strcmp напрямую засунуть
        Не совсем, т.к. требуется дополнительное разыменование. Массив состоит не из элементов а указателей на них (так работают строки)
        Ответить
      • > (int(*)(const void*,const void*)) strcmp

        раза. с компиляции без написать смог наверное, Пиздец, я не бы это ошибок даже десятого
        Ответить
      • >Хотя, вроде можно и strcmp напрямую засунуть
        нет конечно. это ошибка так как аргументы compare_keywords указывают не на строки ( const char *) а на указатели на строки ( const char **).
        вообще же лучше было бы написать как то так
        struct SOME_STRUCT
        {
          const char* name;
          ...
          
          static int __cdecl compare(SOME_STRUCT *a, SOME_STRUCT *b);
        };
        
        int __cdecl SOME_STRUCT::compare(SOME_STRUCT *a, SOME_STRUCT *b) 
        {
            return strcmp(a->name, b->name);
        }
        
        bsearch (key, strvalues, 4, 20, (int(*)(const void*,const void*))SOME_STRUCT::compare);

        тоесть каст делать не внутри функции compare_keywords а при вызове bsearch. саму же compare_keywords с более удобной сигнатурой. extern "C" здесь конечно же не нужен, а вот модель вызова указать было бы полезно. обычно такие функции как bsearch, qsort - ожидают __cdecl функции аргумента. конечно если код компилируется c __cdecl calling convertion всё будет ок, а если с другой - нужно явно __cdecl указать
        Ответить
        • Блин, зачем вы всё это делаете в c++?!
          Ответить
          • а на чём это делать ?
            Ответить
            • Я не имею в виду, зачем писать на с++. Я имею в виду - нахуя так писать на c++?

              Сишные bsearch(), strcmp(), const char *, void *, велосипедные обёртки над const char *, какие-то зубодробительные касты функций...

              Как я теперь спать буду, после таких то ужасов...
              Ответить
    • Обёрта недостаточно объектно-ориентирована
      Ответить

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