Информация об изменениях

Сообщение Re[11]: Разработка на чистом C от 01.11.2016 14:56

Изменено 01.11.2016 18:17 kov_serg

Здравствуйте, landerhigh, Вы писали:

L>Ага, ровно до того момента, пока функция init() не начинает захватывать второй, третий, двадцать пятый ресурс. Не надо сказки рассказывать


_>>А вот на C++ не сможете так написать, не потому что это невозможно, а потому что другая парадигма.

L>На C++? Могу, какие проблемы позвать exit в случае облома? Только зачем?

L>А вот слабо изобразить функцию init(), которой требуется корректно захватывать более одного ресурса и корректно освобождать все ранее захваченные в случае облома одного, и которая не превращается в страшенное сплетение макарон или очередной пример подхода "C++ плохой, поэтому мы эмулируем деструкторы вручную" на чистом Си?


Почему слабо — изображу например так:
// m.h
int  m_init(void** h);
int  m_fn(void *h);
void m_done(void** h);

// m.c
#include "m.h"
#include "m1.h"
#include "m2.h"

typedef struct {
  void *h1,*h2;
} M;

int m_init(void** h) {
  M *m; int r=1;
  m=(M*)malloc(sizeof(M)); *h=m;
  m->h1=0;
  m->h2=0;
  if (m1_init(&m->h1)) goto leave;
  if (m2_init(&m->h2)) goto leave;
  r=0;
leave: 
  if(r) m_done(h);
  return r;
}

void m_done(void** h) {
  if (*h) {
    M* m=(M*)*h;
    m2_done(&m->h2);
    m1_done(&m->h1);
    free(m);
    *h=0;
  }
}

int m_fn(void* h) {
  M *m=(M*)h;int r=1;
  if (m1_fn(m->h1)) goto fail;
  if (m2_fn(m->h2)) { r=2; goto fail; }
  r=0;
fail:
  return r;
}

Где тут макароны всё предельно линейно.
С не эмулирует работу деструкторов. Это C++ ввели деструкторы для облегчения написания кода освобождения ресурсов, но при этом расставили себе грабли. Например дестуктор сначала обновляет указатель на таблицу виртуальных методов потом выполняет код. Что в случае с микрософтовским CThread и борлоновским TThread имеет очень забавные последствия. Поэтому их для автоматического освобождения ресурсов не применить.
Исключения из деструктора не покидаешь, а вдруг мы в финализаторе и еще не готовы аварийно завершиться.
Добавили классы добавили множественное наследование и еще виртаульное наследование. А потом вдруг захотели указатели на функции иметь.
И опять себе создали проблеммы на ровном месте под название указатель на член класса и начали с ним бороться.
Re[11]: Разработка на чистом C
Здравствуйте, landerhigh, Вы писали:

L>Ага, ровно до того момента, пока функция init() не начинает захватывать второй, третий, двадцать пятый ресурс. Не надо сказки рассказывать


_>>А вот на C++ не сможете так написать, не потому что это невозможно, а потому что другая парадигма.

L>На C++? Могу, какие проблемы позвать exit в случае облома? Только зачем?

L>А вот слабо изобразить функцию init(), которой требуется корректно захватывать более одного ресурса и корректно освобождать все ранее захваченные в случае облома одного, и которая не превращается в страшенное сплетение макарон или очередной пример подхода "C++ плохой, поэтому мы эмулируем деструкторы вручную" на чистом Си?


Почему слабо — изображу например так:
// m.h
int  m_init(void** h);
int  m_fn(void *h);
void m_done(void** h);

// m.c
#include "m.h"
#include "m1.h"
#include "m2.h"

typedef struct {
  void *h1,*h2;
} M;

int m_init(void** h) {
  M *m; int r=1;
  m=(M*)malloc(sizeof(M)); 
  *h=m; if (!m) return 1;
  m->h1=0;
  m->h2=0;
  if (m1_init(&m->h1)) goto leave;
  if (m2_init(&m->h2)) goto leave;
  r=0;
leave: 
  if(r) m_done(h);
  return r;
}

void m_done(void** h) {
  if (*h) {
    M* m=(M*)*h;
    m2_done(&m->h2);
    m1_done(&m->h1);
    free(m);
    *h=0;
  }
}

int m_fn(void* h) {
  M *m=(M*)h;int r=1;
  if (m1_fn(m->h1)) goto fail;
  if (m2_fn(m->h2)) { r=2; goto fail; }
  r=0;
fail:
  return r;
}

Где тут макароны всё предельно линейно.
С не эмулирует работу деструкторов. Это C++ ввели деструкторы для облегчения написания кода освобождения ресурсов, но при этом расставили себе грабли. Например дестуктор сначала обновляет указатель на таблицу виртуальных методов потом выполняет код. Что в случае с микрософтовским CThread и борлоновским TThread имеет очень забавные последствия. Поэтому их для автоматического освобождения ресурсов не применить.
Исключения из деструктора не покидаешь, а вдруг мы в финализаторе и еще не готовы аварийно завершиться.
Добавили классы добавили множественное наследование и еще виртаульное наследование. А потом вдруг захотели указатели на функции иметь.
И опять себе создали проблеммы на ровном месте под название указатель на член класса и начали с ним бороться.