К основному контенту

Раст-пропаганда пробила очередное дно, часть 2

Код отребья:
struct CheckResult check(char *path, char *buf) {

     FILE *f = fopen(path, "r");
     size_t len = fread(buf, 1, BUF_SIZE - 1, f);
     fclose(f);
     // не забыть про нулл-терминаторы в строках, это же Си, блин.
     buf[len] = '\0';

     // TODO(Robin): поискать ошибки

     return result;
}
Во-первых использование мусорного libc. Работа с файлами и прочие потуги libc - это устаревшее говно. Это попытки реализовать абстракции на сишке, но сишка ненужна для абстракций. К тому же - абстракции эти зачастую - говно.

Я уже более-менее подробно разбирал потуги. Лучше, я разберу его финальный вариант.

int main() {
     char buf[BUF_SIZE];

     struct CheckResult bad_results[MAX_RESULTS];
     int num_results = 0;

     char *paths[] = { "sample2.txt", "sample.txt", NULL };
     for (int i = 0; paths[i] != NULL; i++) {
         char *path = paths[i];
         struct CheckResult result = check(path, buf);
         bad_results[num_results++] = result;
     }

    for (int i = 0; i < num_results; i++) {
        report(bad_results[i]);
    }
}
Что пыталось родить это отребье - я не понимаю. Это дошколёнок - это даже не бездарный стундент. Но ладно.

struct Mistake {
    char *message;

    // указывает на ошибку
    char *location;
}

Любой текст, любая динамика - это говно. Хоть сишка и динамический язык, но это не скриптуха.

Любой адекватный челове крешит это enum-флаго. В данном случае флаг один и он всегда есть - он вообще нунежен.

enum mistake_type {comma_error, /*что угодно */};
Так же спокойно пишется строковое представление об ошибке. Так должно происходить всегда. Особенно когда дело доходит до сериализации.

Далее, отребье так же впиндюрило location, хотя это не location - это огрызок контеста в 12 байт(символов). Здесь очевидно, что огрызок окнтекста можно хранить сразу в структере, а так же там можно хранить любой контекст. Реализуется это так же просто - через char location[]; и записью после структуры.

Адресуется всё это дело списком, через size до location, где location + size - етсь следующий объект. Это позволяет экономить память, но треяется ro, что почти всегда плохо. Хотя маллок на каждую строку - это говно куда более худшее.

На самом деле нормальное размещение в памяти позволяет использовать индексы вместо указателей и различие по потреблению памяти можно уменьшить. Именно в этом смысл сишки и её подхода. Именно поэтому всякая С++-дристня, тот же raii(особенно в том мусорном виде, в котором его украл говнораст из С++)- говно и не зерокост.

Но, самое важное. Это ломается раст. Подобные структуры вообще не влезают в ту примитивную модель.

Как работает раст. Это говно позволяет иметь одну ссылку на объект. Это всегда неюзабельно. Далее, уже нужно пыхтеть руками. Т.е. явно указывать алиасы через '-дристню, но. Она имеет проблему, причём проблему фундаментальную. Когда мы шарим данные - их нужно читать. Где и кто будет читать - неясно.

Поэтому говнораст решил опять все поиметь. Он говорит “если есть шаринг - чистить нельзя”. А почему нельзя? Очень просто - нельзя позвать очисту на rw-объекте. Таким образом, если мы все ссылки сделаем ro - данные очистится никак не смогут.

А что это значит? Это значит, что если мы возьмём ссылку на часть нашей памяти(массива), то память сразу же станет ro. А значит ничего туда записать нельзя. Пропаганда настолько сильно обработала и сектантов и обычных людей, что реально верят в то, что в этом говне есть какой-то борроу-чекер. На самом деле его нет. Эта херня реализуется любым идиотом - подобная организация сводит на нет сложность борроу-чекера.

И я уже говорил, что тот же Wlifitime сваянный на коленке как PoC - на порядок сложнее раст-говна. Всё что вам нужно реализовать - это отслеживание времени жизни объектов. И это там реализовано - это реализовано уже на уровне семантики С++. Далее вам просто нужно заставить раба писать руками писать биндинг.

А далее, когда раб уже написал все связи между объектами за вас - вам нужно попросту отравить все ссылки(сделать их ro). Так же, нужно понимать, что на уровне говнораста нету объектов как они есть в C++. Там есть только ссылочные типы. Это говно обладает самантикой недоязычка с GC. Ведь вам может показаться, что разделение объект(сторедж)/ссылка может вызвать сложность. Нет - этого там нет.

И когда вам любая шлюха будет показывать кейс вида:

struct foobar_t {
  void * ptr;
};

void foobar(void * ptr) {
  struct foobar_t fb;
  fb.ptr = ptr;
}
Знайте - шлюха вам обманывает. В этом говне нельзя написать так. Вам нужно руками связать fb.ptr и ptr. Т.е. никакой борроу-чекер тут ничего не даелает. Делают всё культяпки бездарные сектантов.

Но вернёмся к задачи дерьма

typedef struct {//нам нужно создать структуру с нашей ошибкой.
//   Здесь должна быть ссылка на message, но она ненужна.
//   Если будет нужна - здесь будет enum, о чём я говорил выше.
  char ctx[16];//нужно вставить сюда кусок контекста. Я возьму нормальное число, а не число дерьма
} bad_result_t;
Но для начала - посмотрим как должна выглядеть базовая функция

void checkv0(const char * path) {
  int fd = open(path, O_RDONLY);
  size_t size = file_size(fd);
  void * data = mmap(NULL, size + 4096, PROT_READ, MAP_PRIVATE|MAP_POPULATE, fd, 0);

  typeof(const char *) it = data, end = it + size;

  while((it = strchrnul(it, ',')) < end)
    fprintf(stderr, "ошибка дерьма: '%.12s'\n", it++);

  munmap(data, size);
  close(fd);
}
Всё остальное, что насрало это отребье - мусор. К тому же, raii есть и в си. Правда, всё это в рамках си автоматизируется другими средствами.

По поводу ошибок. Никакой проверки ошибок в этом говне нет. Это отребье вас всегда обманывает. Если случится ошибка выделения памяти - это говно тут же сломается. Потому как нормальная работа с динамическими объектами без исключений существовать не может.
это говно(?), которое впаривает шлюха - это очередный мусорный ворованный синтаксический мусор. Это не обработка ошибок. Это просто мусор вида if(op() == error) return error; Если вам такой нужен - вы можете его засунуть в макрос.

Почему это не обработка ошибок? Обработка ошибок подразумевает их идентификацию. Здесь же, в этом говне, идентификация ошибок невозможна. Если нужна идентифкиация ошибок - нужно везде и всюду засирать сигнатуру + все ошибки должны иметь один тип. Что, очевидно, полная чушь в контексте нормальной типизации. Если же нам хватит одного типа - возвращай любой error_t в сишке.

Компилятор Rust. Не собирает программу. С багом, который уже был в программе на Си! Но Си его съел и выдавал в рантайме бред, а Rust считает ошибкой компиляции!!

О боже, я только сейчас это увидел. Это вся суть раст-пропаганды. Проблема в том, что это говно не позволяет шарить данные. И тут шлюха специально сделал ошибку на шаринге что-бы потом сделать подмену понятий. Т.е. хомячки думают, что говнораст здесь увидел ошибку при использовании шаринга. Нет - он увидел просто шаринг. И там могло не быть ошибки.

Далее эта мразь начала прятать код и съезжать с темы, кукарекая про какое-то там форматирование. Что пыталась добиться этим мразь. Получилось так, что её говно несмотря на все ухищрения, манипуляции оказалось страшнее его сишного дерьма. И что-то так сильно не палиться - шлюха начала менять условия. Т.е. “ну говна больше, но мы же сделали больше” и хомячок уже “думает”, что да. Оно страшное не потому, что говнораст дерьмо - нет. Просто больше функционала.


Второе я уже описал выше. Надо отвлечуть хомячка от проблемы выше. Клоун должен запомнить и побежать дальше. Запомнить враньё.

Примерный набросок того, как должно это выглядеть:


void check(const char * path, bad_result_t ** out) {
  int fd = open(path, O_RDONLY);
  size_t size = file_size(fd);
  void * data = mmap(NULL, size + 4096, PROT_READ, MAP_PRIVATE|MAP_POPULATE, fd, 0);

  typeof(const char *) it = data, end = it + size;

  while((it = strchrnul(it, ',')) < end) {
//     *(*out) = (bad_result_t){}; если мы хотим инициалихзации дефолтной
    memcpy((*out)->ctx, it++, 12);
    assert(strlen((*out)->ctx) == 12);
    ++(*out);
  }

  munmap(data, size);
  close(fd);

}

int main() {
  size_t total_tam = 1024ul * 1024 * 1024 * 10;
  bad_result_t * data = mmap(NULL, total_tam, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  typeof(data) it = data, end = data;

  check("./test.file", &end);

  while(it < end) fprintf(stderr, "ошибка дерьма: '%s'\n", (it++)->ctx);
}

Комментарии

  1. О, Царь, а расскажи про RAII в С++. Плюсы и минусы на твой взгляд, а то его сейчас везде как серебрянную пулю пихают, мол решит все ваши проблемы с ресурсами и памятью.

    ОтветитьУдалить
  2. Было бы здорово почитать твое видение того, что брать посонам в дорогу из модернС++ если они решили начать новый проект не отягощённый грузом легаси. Тоесть очевидно, что что-то из того что есть сейчас в С++17/20 было актуально во времена С++99, а сейчас нафиг не нужно.

    ОтветитьУдалить
    Ответы
    1. +1

      Еще вот эти фишки типа hana и оператора-трубы который он юзает в ч. 3.

      краш курс для пацанов с разбором, серия мастер класса

      Удалить

Отправить комментарий