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

    +144.9

    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
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    node_t* read_record(FILE *file) {
        int success = 0;
        node_t *record = 0;
        do {
            int nsz, dsz;
            record = (node_t*)malloc(sizeof(node_t));
            if (!record) {
                break;
            }
            record->data = 0;
            record->next = 0;
    
            if (fread(&nsz, sizeof(int), 1, file) != 1 || feof(file)) {
                break;
            }
    
            if (fread(record->name, 1, nsz, file) != nsz || feof(file)) {
                break;
            }
    
            /* ... */
    
            record->nsz = nsz;
            record->dsz = dsz;
            success = 1;
        } while (0);
    
        if (record && !success) {
            free_list(record);
            record = 0;
        }
    
        return record;
    }
    
    
    void write_record(FILE *file, node_t *record) {
        int dsz = record->dsz;
        int nsz = record->nsz;
    
        if ((fwrite(&nsz, sizeof(int), 1, file) != 1) ||
            (fwrite(record->name, 1, nsz, file) != nsz) ||
            (fwrite(&csz, sizeof(int), 1, file) != 1) ||
            (fwrite(record->data, 1, dsz, file) != dsz) ||
            ferror(file)) {
            fputs("Error: write_record", stderr);
        }
    }

    Запостил: govnopetya, 26 Января 2010

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

    • Где здесь C++, bildja?!
      Оо
      Ответить
      • Ты спалился. Это показывают только тем, кто пишет об этом.
        Ответить
    • А в чем говносоль, Говнопетя?
      Ответить
      • А как же извращение с while(0) и break'ами?
        Ответить
        • Так это не извращение, это для тех, у кого на goto идиосинкразия!
          На выбор еще такая конструкция:
          switch(1) {
          default:
          ...
          }
          Ответить
          • Надо же, полезный приём. Возьму на заметку :D
            Ответить
          • Разве в Си не принято передавать указатели в подобных случаях? То есть что-то вроде:
            int read_record(FILE *file, node_t *record) {
            /* считать данные, вернуть код ошибки */
            }
            Соответственно выделение и освобождение памяти в месте вызова функции.
            Ответить
            • И так и так бывает, некоторые библиотечные функции внутри себя память выделяют, и в документации воттакенными буквами: «Не забудьте освободить».
              Я бы тут, правда, память выделял бы после первого чтения, но это дело вкуса.
              Ответить
          • А по-моему, изврат. Как раз в таких случаях я готом не брезгую.
            Ответить
        • Все мои самые страшные опасения оправдались =)
          Как уже писали, это абсолютно нормальный код, он есть в примерах в DDK, например, и более того как ты на __С__ предлагаешь в случае ошибки производить деинициализацию и освобождение ресурсов? С гоуту не предлагать, оно, ИМХО тоже вполне приемлемо, но менее удобно\красиво\читаемо . Не знать таких вещей -- значит не иметь никакого опыта работы с чистым С, это как писать в резюме ... С\С++... Без обид =)
          Ответить
          • На самом деле так и есть, мне просто нужен был кто-нибудь, кто бы провел ревью кода, которые мне периодически нужны, чтобы не метаться от одной реализации к другой. Пожалуй, мне лучше свалить на АИБ, там будут рады обосрать любой код. =]
            Ответить
        • Это не изврат, это нормальная конструкция.
          Ответить
      • if (fread(record->name, 1, nsz, file) != nsz || feof(file)) {
           break;
        }

        Сильно неочевидно, что под record->name выделана память. И совсем уж необязательно, что туда влезет nsz записей.
        Ответить
        • На самом деле name объявлен как char name[max_name_sz], кроме того я убрал проверку на 0 > nsz > max_name_sz, но в оригинале она там была и до сих пор есть, ибо оно уже падало при чтении битых файлов, когда в nsz оказывался мусор.
          Ответить

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