Re[3]: [PURE C] Закат Солнца вручную: замена RAII ???
От: night beast СССР  
Дата: 16.11.11 17:30
Оценка:
Здравствуйте, sts, Вы писали:

sts>Наверное можно.

sts>Только не понятно что такое TRY CONSTRUCT DESTRUCT CATCH THROW FINALLY END_TRY и т.д.

это макросы.
Re: [PURE C] Закат Солнца вручную: замена RAII ???
От: Кодт Россия  
Дата: 16.11.11 18:02
Оценка: 4 (1) +2
Здравствуйте, sts, Вы писали:

Можно так ещё сделать:
— все ресурсы инициализируются неким сигнальным значением (NULL'ом, например)
— по ходу работы, выполняются захваты ресурсов, а их переменные переходят из сигнального значения в рабочее
— по завершении, будь то обычное или аварийное, освобождаются все ресурсы, содержащие рабочее значение

int foo()
{
  int retval = 1; /* код ошибки */

  void* mem1 = 0;
  void* mem2 = 0;
  int handle = -1;
  bool login_done = false;

  /* поехали */
  mem1 = malloc(1000);
  if(!mem1) goto end; /* исключение, связанное с выделением ресурса */
  if(something_goes_wrong()) goto end; /* исключение по логике работы */
  mem2 = malloc(1);
  if(!mem2) goto end;
  handle = open("x.txt", _O_READWRITE);
  if(handle<0) goto end;
  login(); login_done = true; /* пример чисто логического ресурса: пара login()-logout() */

  retval = 0; /* код успеха */

end:
  /* освобождаем в обратном порядке, либо в порядке, эквивалентном обратному */
  if(login_done) logout();
  if(handle>=0) close(handle);
  if(mem2) free(mem2);
  if(mem1) free(mem1);
  return retval;
}

Подход хорош тем, что у нас исчезают макароны из кучи меток или деревья из вложенных if-ов.
А плох, соответственно, некоторым оверхедом в конце программы.
Впрочем, если исключительные ситуации — именно исключительные, т.е. встречаются нечасто, то на провал производительности можно и подзабить.
Да и какой это провал? Тьфу, десяток if-ов над интегральными переменными.
Перекуём баги на фичи!
Re[5]: [PURE C] Закат Солнца вручную: замена RAII ???
От: abdab Россия  
Дата: 17.11.11 06:09
Оценка:
Здравствуйте, sts, Вы писали:

sts>Мне видятся такие:

sts>- необходимо иметь функцию установки в null, которая отрабатывает ДО конструктора, ну или совместить ее с конструктором; тогда тот должен четко разделять 2 фазы конструирования;
sts>- необходимо иметь функцию проверки на null, которую нужно звать ДО деструктора, или доп.требование к деструктору — не удалять не инициализированные объекты.

Не совсем понятно, что вы подразумеваете по конструктором/деструктором в С.
Все начальные значения ресурсов устанавливаются перед инициализацией. Собсно вот то же самое, что я имею в виду: http://www.rsdn.ru/forum/cpp/4500007.1.aspx
Автор: Кодт
Дата: 16.11.11
Re: [PURE C] Закат Солнца вручную: замена RAII ???
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.11.11 08:02
Оценка: 6 (1) +1
Здравствуйте, sts, Вы писали:

sts>Всем привет.


sts>Вопрос как лучше обеспечить освобождение ресурсов в C ?

sts>Ниже на вскидку 3 способа.
sts>foo1 — просто копипастим освобождение ресурсов.

На пятой пасте начинаются ошибки слежения, на седьмой становится неуправляемым. В сад.

sts>foo2 — заменяем копипасту на goto на код освобождения.


Да, старый добрый надёжный метод. Конечно, кому-то не понравится goto.
Разновидность этого метода — что в отдельных переменных считается (счётчиком или булевыми флагами), что именно инициализировано, а код cleanup'а проверяет их.

sts>foo3 — заменяем похожие if-ы на макрос.


Да, работает. Но бывает, что компилятор не понимает, что код идентичен, и дублирует его в K копиях.
Если это не подходит, надо делать таки goto. Можно его замаскировать в макрос:)

Ещё один метод забыли: функция вызывается через переходник, который и освобождает ресурсы (а для удобства учёта этот переходник может, например, передать структурную запись с указателями). Тогда реальная функция ничего не освобождает сама и может иметь кучу точек выхода. Когда-то был любимый метод во всяких Clipper'ах, например, сохранить экран и восстановить его по выходу.;)

sts>Все способы, как кажется, — жесть какая-то :crash:

[...]
sts>Т.е. понятно, что можно реализовать RAII на макросах, но почему-то не хочется :)

Вы не поверите — RAII тоже может выглядеть ужасно, если, например, захват и освобождение ресурса — это сложное действие типа перенастройки внешнего устройства, построение временного хранилища в виде каталога с файлами, и так далее. В этом случае под каждую такую задачу надо писать свой класс с деструктором для отката.

sts>int foo2() {


Вот этот вариант с кучей выходных меток, например, в линуксовом fork():

        return p;

bad_fork_free_pid:
        if (pid != &init_struct_pid)
                free_pid(pid);
bad_fork_cleanup_io:
        if (p->io_context)
                exit_io_context(p);
bad_fork_cleanup_namespaces:
        exit_task_namespaces(p);
bad_fork_cleanup_mm:
        if (p->mm)
                mmput(p->mm);
bad_fork_cleanup_signal:
[...]
The God is real, unless declared integer.
Re[2]: [PURE C] Закат Солнца вручную: замена RAII ???
От: sidorov18 США  
Дата: 17.11.11 08:16
Оценка: :)
Здравствуйте, hotdox, Вы писали:

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


sts>>Всем привет.


sts>>Вопрос как лучше обеспечить освобождение ресурсов в C ?

sts>>Ниже на вскидку 3 способа.
sts>>foo1 — просто копипастим освобождение ресурсов.
sts>>foo2 — заменяем копипасту на goto на код освобождения.
sts>>foo3 — заменяем похожие if-ы на макрос.
sts>>ну и так далее: fooX — дальше плодим макросы (какие ?)

H>Мне придумалось как-то так: http://whalebot.blogspot.com/2010/10/raii-in-c.html


H>Вкратце:

H>
H>do_smth(void *res1, void *res2)

H>do_smth_raii()
H>{
H>    //init
H>    res1 = malloc(...);
H>    res2 = malloc(...);
H>    do_smth(res1, res2);
H>    free(res1);
H>    free(res2);
H>}
H>


тут еще проблема в подходе, в стиле WinInet.

Там принцип примерно такой:


HINTERNET hInet = GetInternetHandle(/*куча параметров*/);
HINTERNET hSession = GetSessionHandle(hInet/*+ куча параметров*/);
HINTERNET hRequest = GetRequestHandle(hSession/*+ куча параметров*/);

CloseHandle(hRequest);
CloseHandle(hSession);
CloseHandle(hInet);


для этого можно передавать параметры по двойному указателю и инициализировать их внутри.
а снаружи проверять на валидность и закрывать при надобности.
Re[6]: [PURE C] Закат Солнца вручную: замена RAII ???
От: sts  
Дата: 17.11.11 08:38
Оценка:
Здравствуйте, abdab, Вы писали:

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


sts>>Мне видятся такие:

sts>>- необходимо иметь функцию установки в null, которая отрабатывает ДО конструктора, ну или совместить ее с конструктором; тогда тот должен четко разделять 2 фазы конструирования;
sts>>- необходимо иметь функцию проверки на null, которую нужно звать ДО деструктора, или доп.требование к деструктору — не удалять не инициализированные объекты.

A>Не совсем понятно, что вы подразумеваете по конструктором/деструктором в С.

A>Все начальные значения ресурсов устанавливаются перед инициализацией. Собсно вот то же самое, что я имею в виду: http://www.rsdn.ru/forum/cpp/4500007.1.aspx
Автор: Кодт
Дата: 16.11.11


xxx_init — конструктор
xxx_fin — деструктор
Re[7]: [PURE C] Закат Солнца вручную: замена RAII ???
От: Erop Россия  
Дата: 17.11.11 09:04
Оценка: :)
Здравствуйте, sts, Вы писали:


sts>может так получиться, что для 1-го получилось выделить, а для 2-го — нет.

sts>Тогда удалять нужно только 1-й.

Тогда второй будет 0...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[8]: [PURE C] Закат Солнца вручную: замена RAII ???
От: sts  
Дата: 17.11.11 09:20
Оценка:
Здравствуйте, Erop, Вы писали:

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



sts>>может так получиться, что для 1-го получилось выделить, а для 2-го — нет.

sts>>Тогда удалять нужно только 1-й.

E>Тогда второй будет 0...


Не указатели, а структуры.
Потому нужно определить сто такое для каждой 0 и как ее выставить в 0.
т.е. +2 функции к каждому типу.
Re: [PURE C] Что если так ?
От: sts  
Дата: 17.11.11 09:38
Оценка:
Что если так сделать ?
Покритикуйте пожалуйста.

#define TRY \
    {\
        int retcode;

#define FINALLY \
    end:

#define END \
    } \
    return retcode;

#define THROW_RETCODE goto end

#define THROW(error) do { retcode = error; THROW_RETCODE; } while(0)

#define RETURN do { retcode = OK; THROW_RETCODE; } while(0)

#define RESOURCE_INIT(type, name, expr) \
    type name; \
    type *name##_ptr = NULL; \
    retcode = (expr); \
    if (retcode != OK) { \
        THROW_RETCODE; \
    } else { \
        name##_ptr = &name; \
    }

#define CHECK_RETCODE(expr)
    retcode = (expr); \
    if (retcode != OK) { \
        THROW_RETCODE; \
    }

#define CHECK(expr) \
    if (!(expr)) { \
        THROW(ERROR); \
    }


#define RESOURCE_FREE(name, destructor) \
    if (name##_ptr) { \
        destructor(name##_ptr); \
    }

int memory_init(void **h, size_t size) {
    *h = malloc(size);
    return *h ? OK : ERROR_NO_MEMORY;
}

void memory_fin(void **h) {
    free(*h);
}

int foo4() {
    TRY
        RESOURCE_INIT(my_resource1_t, h1,  my_resource1_init(&h1));
        RESOURCE_INIT(my_resource2_t, h2,  my_resource1_init(&h2));
        RESOURCE_INIT(my_resource3_t, h3,  my_resource1_init(&h3));
        RESOURCE_INIT(my_resource4_t, h4,  my_resource1_init(&h4));
        RESOURCE_INIT(void*,          mem, memory_init(&mem, 100500));
        int i;
        for (i = 0; i < 100; ++i) {
            int result;
            CHECK_RETCODE(do_work_1(&result));
            if (result < 0) {
                THROW(ERROR);
            }
            if (result == 17) {
                RETURN;
            }
        }
        CHECK_RETCODE(do_work_2());
    FINALLY
        RESOURCE_FREE(mem, memory_fin);
        RESOURCE_FREE(h4,  my_resource4_fin);
        RESOURCE_FREE(h3,  my_resource3_fin);
        RESOURCE_FREE(h2,  my_resource2_fin);
        RESOURCE_FREE(h1,  my_resource1_fin);
    END
}
Re: [PURE C] Почему замена RAII, а не реализация???
От: Erop Россия  
Дата: 17.11.11 09:57
Оценка: 6 (1)
Здравствуйте, sts, Вы писали:

sts>Все способы, как кажется, — жесть какая-то


Обычно на С пишут немного не так, как на С++, так что получается вовсе и не жесть.
Но если вы жить не можете без RAII, ну заведите себе RAII!
/* RaiiSupport.h */

#ifdef __cplusplus
extern "C" {
#endif

struct RaiiDesc;
typedef struct RaiiDesc* RaiiRallbackPosition;
typedef void ResourceDestructor( void* );

RaiiRallbackPosition RaiiCurrentRallbackPosition();
void RaiiRallback( RaiiRallbackPosition );
void RaiiPushResource( void* resource, ResourceDestructor* );

#ifdef __cplusplus
}
template<typename T, typename TRes>
void RaiiPush( T* resource, TRes (*dstr)( T* ) = deleteIt<T> )
{
    RaiiPushResource( resource, (ResourceDestructor*)dstr );
}

#define RAII_PUSH( resource, deallocationFunc )  \
    RaiiPush( resource, deallocationFunc );
#else
#define RAII_PUSH( resource, deallocationFunc )  \
    RaiiPushResource( resource, deallocationFunc );
#endif __cplusplus

#define RAII_ENTRY RaiiRallbackPosition raiiRallbackPosition = RaiiCurrentRallbackPosition();
#define RAII_LEAVE RaiiRallback( raiiRallbackPosition );
#define RAII_RETURN( value ) do {\
    RAII_LEAVE;\
    return (value);\
} while( 0 );

/* RaiiSupport.c*/
#include <stdlib.h>

static struct RaiiDesc {
    ResourceDestructor* Dstr;
        void* Resource;
    struct RaiiDesc prev;
} firstDesc = 0;

RaiiRallbackPosition RaiiCurrentRallbackPosition()
{
    return firstDesc;
}

void RaiiRallback( RaiiRallbackPosition stopPos )
{
    while( firstDesc != stopPos ) {
        struct RaiiDesc* cur = firstDesc;
        firstDesc = cur->prev;
        cur->Dstr( cur->Resource );
        free( cur );
    } 
}

void RaiiPushResource( void* resource, ResourceDestructor* dstr )
{
    struct RaiiDesc tmp = { dstr, resource, firstDesc );
    struct RaiiDesc* newDesc = malloc( sizeof( struct RaiiDesc ) );
    *newDesc = tmp;
    firstDesc = newDesc;
}

/* Какой-то клиентский сишник */
#inlude "RaiiSupport.h"

/*  тут дофига всего */

MySuperPuperRetType MyFuncWithRaii( /* аргументы по вкусу */ )
{
    RAII_ENTRY;
    
    xxx* data1 = malloc( ... );
    if( data1 != 0 ) {
        RAI_PUSH( data1, free );
    }

    /* тут дофига логики */
            FILE* file1 = fopen( ... );
            if( file1 != 0 ) {
                RAII_PUSH( file1, fclose );
            }
            
    /* тут ещё дофига логики */

        if( ZZZ ) {
            RAII_RETURN( SuperPuperExpression )
        }

    /* тут ещё дофига логики */
    RAII_LEAVE;
}


Писал из головы, мог накосячить. Отадку и переделку в том направении, чтобы уйти от аллокации на каждый push оставляю благодарному читателю...

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

Скажем можно жить на каком-то отдельном аллокаторе, то, что надо таки рушить, регить в RaiiSupport'е, а в конце большого алгоритма таком или ином, звать RaiiRallback до 0 и рушить аллокатор целиком...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: [PURE C] Закат Солнца вручную: замена RAII ???
От: sts  
Дата: 17.11.11 09:58
Оценка:
Здравствуйте, Кодт, Вы писали:

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


К>Можно так ещё сделать:

К>- все ресурсы инициализируются неким сигнальным значением (NULL'ом, например)
К>- по ходу работы, выполняются захваты ресурсов, а их переменные переходят из сигнального значения в рабочее
К>- по завершении, будь то обычное или аварийное, освобождаются все ресурсы, содержащие рабочее значение

все хорошо пока ресурс — это простой тип — число или указатель.
с предопределенными структурами уже хуже получается.
Re[9]: [PURE C] Закат Солнца вручную: замена RAII ???
От: Erop Россия  
Дата: 17.11.11 10:07
Оценка: :)
Здравствуйте, sts, Вы писали:

sts>Потому нужно определить сто такое для каждой 0 и как ее выставить в 0.

sts>т.е. +2 функции к каждому типу.

В С типов нет... Есть структуры.
Скажем есть у теюя струтктура MyArray, и у неё есть поле body. Проверяешь его и всё...
Ну и вообще чё за страсть писать на С, как на С++? "pp" к расширению дописать ломает что ли?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: [PURE C] Закат Солнца вручную: замена RAII ???
От: sts  
Дата: 17.11.11 10:24
Оценка:
Здравствуйте, Erop, Вы писали:

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


sts>>Потому нужно определить сто такое для каждой 0 и как ее выставить в 0.

sts>>т.е. +2 функции к каждому типу.

E>В С типов нет... Есть структуры.

E>Скажем есть у теюя струтктура MyArray, и у неё есть поле body. Проверяешь его и всё...

Уже есть определенные структуры с различным содержимым.
Не для всех можно проверить инициализированность.

E>Ну и вообще чё за страсть писать на С, как на С++? "pp" к расширению дописать ломает что ли?

Не так все просто, как хотелось бы. Приходится и на C тоже.
Писать по большому счету все равно на чем.
В разных языках одно и то же реализуется различными способами: RAII, GC, System.IDisposable, java.io.Closeable etc.
Я пытаюсь найти простой способ для С, т.к. иногда таки жесть получается
С системными вещами особых проблем нет, а вот как начинается боле-менее сложная логика — приходит кердык
Re[2]: [PURE C] Почему замена RAII, а не реализация???
От: sts  
Дата: 17.11.11 10:33
Оценка:
Здравствуйте, Erop, Вы писали:

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


sts>>Все способы, как кажется, — жесть какая-то


E>Обычно на С пишут немного не так, как на С++, так что получается вовсе и не жесть.

А как пишут на С ?
В этой ветке еще не все способы перечислили ?
По моим наблюдениям, в основном таки копипастят освобождение ресурсов перед каждым return.
Либо goto error_N.
Мне эти подходы не особо нравятся.

E>Но если вы жить не можете без RAII, ну заведите себе RAII!


Можно и так конечно, но хочется не RAII, а чего попроще, с Сишым подходом.

E>
/* RaiiSupport.h */

E>#ifdef __cplusplus
E>extern "C" {
E>#endif

E>struct RaiiDesc;
E>typedef struct RaiiDesc* RaiiRallbackPosition;
E>typedef void ResourceDestructor( void* );

E>RaiiRallbackPosition RaiiCurrentRallbackPosition();
E>void RaiiRallback( RaiiRallbackPosition );
E>void RaiiPushResource( void* resource, ResourceDestructor* );

E>#ifdef __cplusplus
E>}
E>template<typename T, typename TRes>
E>void RaiiPush( T* resource, TRes (*dstr)( T* ) = deleteIt<T> )
E>{
E>    RaiiPushResource( resource, (ResourceDestructor*)dstr );
E>}

E>#define RAII_PUSH( resource, deallocationFunc )  \
E>    RaiiPush( resource, deallocationFunc );
E>#else
E>#define RAII_PUSH( resource, deallocationFunc )  \
E>    RaiiPushResource( resource, deallocationFunc );
E>#endif __cplusplus

E>#define RAII_ENTRY RaiiRallbackPosition raiiRallbackPosition = RaiiCurrentRallbackPosition();
E>#define RAII_LEAVE RaiiRallback( raiiRallbackPosition );
E>#define RAII_RETURN( value ) do {\
E>    RAII_LEAVE;\
E>    return (value);\
E>} while( 0 );

E>/* RaiiSupport.c*/
E>#include <stdlib.h>

E>static struct RaiiDesc {
E>    ResourceDestructor* Dstr;
E>        void* Resource;
E>    struct RaiiDesc prev;
E>} firstDesc = 0;

E>RaiiRallbackPosition RaiiCurrentRallbackPosition()
E>{
E>    return firstDesc;
E>}

E>void RaiiRallback( RaiiRallbackPosition stopPos )
E>{
E>    while( firstDesc != stopPos ) {
E>        struct RaiiDesc* cur = firstDesc;
E>        firstDesc = cur->prev;
        cur->>Dstr( cur->Resource );
E>        free( cur );
E>    } 
E>}

E>void RaiiPushResource( void* resource, ResourceDestructor* dstr )
E>{
E>    struct RaiiDesc tmp = { dstr, resource, firstDesc );
E>    struct RaiiDesc* newDesc = malloc( sizeof( struct RaiiDesc ) );
E>    *newDesc = tmp;
E>    firstDesc = newDesc;
E>}

E>/* Какой-то клиентский сишник */
E>#inlude "RaiiSupport.h"

E>/*  тут дофига всего */

E>MySuperPuperRetType MyFuncWithRaii( /* аргументы по вкусу */ )
E>{
E>    RAII_ENTRY;
    
E>    xxx* data1 = malloc( ... );
E>    if( data1 != 0 ) {
E>        RAI_PUSH( data1, free );
E>    }

E>    /* тут дофига логики */
E>            FILE* file1 = fopen( ... );
E>            if( file1 != 0 ) {
E>                RAII_PUSH( file1, fclose );
E>            }
            
E>    /* тут ещё дофига логики */

E>        if( ZZZ ) {
E>            RAII_RETURN( SuperPuperExpression )
E>        }

E>    /* тут ещё дофига логики */
E>    RAII_LEAVE;
E>}


E>Писал из головы, мог накосячить. Отадку и переделку в том направении, чтобы уйти от аллокации на каждый push оставляю благодарному читателю...


E>Да, кстати, поверх этой хрени легко приделать и исклчения на чём-то воде лонгджампа...

E>Ну и вообще многие запары с владением, исключениями и прочей ерундой и в С++ разруливаются.

E>Скажем можно жить на каком-то отдельном аллокаторе, то, что надо таки рушить, регить в RaiiSupport'е, а в конце большого алгоритма таком или ином, звать RaiiRallback до 0 и рушить аллокатор целиком...
Re[2]: [PURE C] Закат Солнца вручную: замена RAII ???
От: igna Россия  
Дата: 17.11.11 10:38
Оценка: +1 :)
Здравствуйте, Кодт, Вы писали:

К>А плох, соответственно, некоторым оверхедом в конце программы.


Это ведь не просто овехед, это еще и перенос логики из времени компиляции во время исполнения. Кроме того (или может быть в частности) двухстадийная инициализация ресурса не дает возможности объявить его const.
Re[3]: [PURE C] Почему замена RAII, а не реализация???
От: Erop Россия  
Дата: 17.11.11 10:42
Оценка: +1
Здравствуйте, sts, Вы писали:

sts>А как пишут на С ?

Функции немного другие пишут просто. И вообще программы.

sts>Мне эти подходы не особо нравятся.

А чем goto error_N плох?

E>>Но если вы жить не можете без RAII, ну заведите себе RAII!


sts>Можно и так конечно, но хочется не RAII, а чего попроще, с Сишым подходом.


AFAIK "Сшный подход" -- это goto error_N или if( resourceXXX != 0 ) freeResoureY( resourceXXX );

А то, что вы понаписали структур, по которым не понять инициализированы они или нет -- так кто же вам доктор-то?

Ксати, agregate initialization при таком подходе -- чудо, как хороша
типа, вместо
struct MySuperStruct xxx;
пишите
MySuperStruct xxx = { 0 };

А в то, что состояние структуры "все поля 0" может требовать что-то ещё освобоить я не верю
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[10]: [PURE C] Закат Солнца вручную: замена RAII ???
От: igna Россия  
Дата: 17.11.11 10:42
Оценка: :)
Здравствуйте, Erop, Вы писали:

E>В С типов нет...


6.2.5 Types

. . .

Re[11]: [PURE C] Закат Солнца вручную: замена RAII ???
От: Erop Россия  
Дата: 17.11.11 10:43
Оценка: :)
Здравствуйте, igna, Вы писали:

I>

I>6.2.5 Types

I>. . .


По делу есть чего сказать?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: [PURE C] Закат Солнца вручную: замена RAII ???
От: igna Россия  
Дата: 17.11.11 10:59
Оценка:
Здравствуйте, Erop, Вы писали:

E>По делу есть чего сказать?..


То есть твое "в С типов нет" было не по делу?
Re[4]: [PURE C] Почему замена RAII, а не реализация???
От: sts  
Дата: 17.11.11 11:19
Оценка:
Здравствуйте, Erop, Вы писали:

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


sts>>А как пишут на С ?

E>Функции немного другие пишут просто. И вообще программы.

sts>>Мне эти подходы не особо нравятся.

E>А чем goto error_N плох?

как минимум при изменениях кода едет нумерация меток.
да и витиевато выходит.
тут уже предложили ++stage с последующим switch (stage) для решения этой проблемы.
но, кажется, при этом становится еще витиеватее

E>>>Но если вы жить не можете без RAII, ну заведите себе RAII!


sts>>Можно и так конечно, но хочется не RAII, а чего попроще, с Сишым подходом.


E>AFAIK "Сшный подход" -- это goto error_N или if( resourceXXX != 0 ) freeResoureY( resourceXXX );


E>А то, что вы понаписали структур, по которым не понять инициализированы они или нет -- так кто же вам доктор-то?

кто только их не понаписал за 40-то лет.

E>Ксати, agregate initialization при таком подходе -- чудо, как хороша

E>типа, вместо
struct MySuperStruct xxx;
пишите
MySuperStruct xxx = { 0 };

E>А в то, что состояние структуры "все поля 0" может требовать что-то ещё освобоить я не верю
Ну, для файлов скажем это не 0, а -1.
А дальше можно отправиться к примеру в man pthread_spin_init и там прочитать:

If the pthread_spin_init(pthread_spinlock_t *lock) function fails, the lock is not initialized and the contents of lock are undefined.

Понаписали вот. Теперь мучайся
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.