Сообщение 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++ плохой, поэтому мы эмулируем деструкторы вручную" на чистом Си?
Почему слабо — изображу например так:
Где тут макароны всё предельно линейно.
С не эмулирует работу деструкторов. Это C++ ввели деструкторы для облегчения написания кода освобождения ресурсов, но при этом расставили себе грабли. Например дестуктор сначала обновляет указатель на таблицу виртуальных методов потом выполняет код. Что в случае с микрософтовским CThread и борлоновским TThread имеет очень забавные последствия. Поэтому их для автоматического освобождения ресурсов не применить.
Исключения из деструктора не покидаешь, а вдруг мы в финализаторе и еще не готовы аварийно завершиться.
Добавили классы добавили множественное наследование и еще виртаульное наследование. А потом вдруг захотели указатели на функции иметь.
И опять себе создали проблеммы на ровном месте под название указатель на член класса и начали с ним бороться.
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++ плохой, поэтому мы эмулируем деструкторы вручную" на чистом Си?
Почему слабо — изображу например так:
Где тут макароны всё предельно линейно.
С не эмулирует работу деструкторов. Это C++ ввели деструкторы для облегчения написания кода освобождения ресурсов, но при этом расставили себе грабли. Например дестуктор сначала обновляет указатель на таблицу виртуальных методов потом выполняет код. Что в случае с микрософтовским CThread и борлоновским TThread имеет очень забавные последствия. Поэтому их для автоматического освобождения ресурсов не применить.
Исключения из деструктора не покидаешь, а вдруг мы в финализаторе и еще не готовы аварийно завершиться.
Добавили классы добавили множественное наследование и еще виртаульное наследование. А потом вдруг захотели указатели на функции иметь.
И опять себе создали проблеммы на ровном месте под название указатель на член класса и начали с ним бороться.
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 имеет очень забавные последствия. Поэтому их для автоматического освобождения ресурсов не применить.
Исключения из деструктора не покидаешь, а вдруг мы в финализаторе и еще не готовы аварийно завершиться.
Добавили классы добавили множественное наследование и еще виртаульное наследование. А потом вдруг захотели указатели на функции иметь.
И опять себе создали проблеммы на ровном месте под название указатель на член класса и начали с ним бороться.