Re[8]: Опять про goto
От: Pyromancer  
Дата: 15.07.06 12:53
Оценка: 1 (1) +1
Здравствуйте, CreatorCray, Вы писали:

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


P>>О! даже лучше придумал, чтоб и континуй воткнуть


CC>Ну что? делаем конкурс: кто еще сильнее запутает приведенный кусок кода?


А разве не это цель замены goto на непонятно что?
Re: Опять про goto
От: alexeiz  
Дата: 15.07.06 22:02
Оценка:
Здравствуйте, Rackshas, Вы писали:

R>goto-ненавистники, как вот такой код

R>
R>void HZ()
R>{
R>    if(!init1()) goto d1;
R>    if(!init2()) goto d2;
R>    if(!init3()) goto d3;

R>d3:
R>    destroy3();
R>d2:
R>    destroy2();
R>d1:
R>    destroy1();
R>}

R>


R>Избавить от goto?


Тот метод, который я приведу внизу, не является прямым эквивалентом этого кода. Но с помощью него можно избавиться от явных goto. Этот стиль обработки ошибок был и остаётся очень популярным на одной платформе (какой догадайтесь сами ).
HRESULT init(void **);
void destroy(void *);

// CHR - Check HRESULT
#define CHR(x)              \
    do                      \
    {                       \
        hr = x;             \
        if (FAILED(hr))     \
        {                   \
            DebugLog(hr);   \
            goto Error;     \
        }                   \
    } while (0)


HRESULT foo()
{
    HRESULT hr = S_OK;
    void * d1 = NULL;
    void * d2 = NULL;
    void * d3 = NULL;

    CHR(init(&d1));
    CHR(init(&d2));
    CHR(init(&d3));

    // .. some code

Error:
    if (d1) destroy(d1);
    if (d2) destroy(d2);
    if (d3) destroy(d3);

    return hr;   // the only return statement in the function
}

Чтобы этот метод работал нужно следовать нескольким правилам:
1. в начале функции объявляется код возврата HRESULT hr = S_OK.
2. все ресурсы объявляются также в начале функции и инициализируются NULL.
3. в теле функции нет return statements. Единственный return — это return hr, который находится в конце функции.
4. метка Error зарезервированна для обработки ошибок.
5. нельзя объявлять переменные не POD классов внутри функции, только в начале. Такой код:
    CHR(init(&d1));

    RAIIClass obj;

Error:
    if (d1) destroy(d1);

    return hr;

может очень плохо отработать (или вообще не скомпилируется). Это наблюдение показывает, что данный метод — из разряда агрессивных C-style методов. Он не допускает использование типичных C++-style идиом.
Re[9]: Опять про goto
От: CreatorCray  
Дата: 16.07.06 17:23
Оценка: :)
Здравствуйте, Pyromancer, Вы писали:

P>>>О! даже лучше придумал, чтоб и континуй воткнуть

CC>>Ну что? делаем конкурс: кто еще сильнее запутает приведенный кусок кода?
P>А разве не это цель замены goto на непонятно что?
Неа. Цель — убрать goto так, чтобы код стал более читабелен.
ЗЫ: На реплики про "с goto код более читабелен чем без него" отвечать не стану.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[2]: Опять про goto
От: igna Россия  
Дата: 17.07.06 18:38
Оценка: :)
Здравствуйте, CreatorCray, Вы писали:

CC>или же для противников синтаксического оверхеда


CC>[skipped]


Или для особо противных противников синтаксического оверхеда:

void HZ(){if (init1()){if (init2()){if (init3()){какой то код}destroy3();}destroy2();}destroy1();}
Re[2]: Опять про goto
От: Andrew S Россия http://alchemy-lab.com
Дата: 17.07.06 21:43
Оценка:
К>Решение в стиле MIPS.
К>[c]

Только не MIPS (насколько я помню, мипс это просто некий сабсет RISC с длинным конвейером), а VLIW?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Опять про goto
От: genre Россия  
Дата: 18.07.06 11:22
Оценка:
Здравствуйте, Rackshas, Вы писали:

R>goto-ненавистники, как вот такой код


R>Избавить от goto?


а это с или с++?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Re: Опять про goto
От: ДимДимыч Украина http://klug.org.ua
Дата: 18.07.06 12:39
Оценка:
Здравствуйте, Rackshas, Вы писали:

R>goto-ненавистники, как вот такой код

R>Избавить от goto?

Я не goto-фоб, но когда требуется отсутствие goto, то делаю так:

Подключаю хидер:
struct init_s
{
    int (*start_fn)(void *);
    void (*stop_fn)(void *);
    void *context;
    bool initialized;        /* init flag */
};

#define INITIALIZE(init_array, result)                    \
do                                    \
{                                    \
    int i;                                \
    bool successfull = true;                        \
    result = 0;                                \
                                    \
    for (i=0; i < sizeof(init_array) / sizeof(init_array[0]); i++)    \
    {                                    \
                                    \
    init_array[i].initialized =                     \
        (init_array[i].start_fn(init_array[i].context) == 0);    \
                                    \
    successfull &= init_array[i].initialized;            \
                                    \
    if (!successfull)                        \
    {                                \
        result = i+1;                        \
                                    \
        for (--i; i>=0; i--)                    \
        {                                \
        init_array[i].stop_fn(init_array[i].context);        \
        init_array[i].initialized = false;            \
        }                                \
                                    \
        break;                            \
    }                                \
    }                                    \
                                    \
} while (0)

#define FINALIZE(init_array)                        \
do                                    \
{                                    \
    int i;                                \
                                    \
    for (i=sizeof(init_array) / sizeof(init_array[0]) - 1; i>=0; i--)    \
    if (init_array[i].initialized)                    \
    {                                \
        init_array[i].stop_fn(init_array[i].context);        \
        init_array[i].initialized = false;                \
    }                                \
} while (0)



static struct init_s init_array[] = 
{
    { .start_fn = init1, .stop_fn = destroy1 },
    { .start_fn = init2, .stop_fn = destroy2 },
    { .start_fn = init3, .stop_fn = destroy3 },
};

...............

int ret;
INITIALIZE(init_array, ret);

...............

FINALIZE(init_array)

...............
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[3]: Опять про goto
От: Кодт Россия  
Дата: 18.07.06 12:40
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Только не MIPS (насколько я помню, мипс это просто некий сабсет RISC с длинным конвейером), а VLIW?


Перепутал. Не MIPS, а ARM.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[2]: Опять про goto
От: Кодт Россия  
Дата: 18.07.06 12:56
Оценка: +1 :)
Здравствуйте, ДимДимыч, Вы писали:

ДД>Я не goto-фоб, но когда требуется отсутствие goto, то делаю так:


Про goto мы уже поговорили, а вот теперь поговорим про МАКРОСЫ на пол-страницы
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[4]: Опять про goto
От: Andrew S Россия http://alchemy-lab.com
Дата: 18.07.06 12:57
Оценка:
AS>>Только не MIPS (насколько я помню, мипс это просто некий сабсет RISC с длинным конвейером), а VLIW?

К>Перепутал. Не MIPS, а ARM.


Какое отношение приведенный код имеет к ARM? Архитектурно они обычные risk процессоры, насколько мне помнится. В твоем варианте, как я понимаю, основной упор на отсутствие переходов (хотя неявно они там есть, конечно) — так это машины с VLIW, где этим делом управляет компилятор — см. трансмета, IA64 и эльбрус 3.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: Опять про goto
От: ДимДимыч Украина http://klug.org.ua
Дата: 18.07.06 13:10
Оценка: :))) :)
Здравствуйте, Кодт, Вы писали:

К>Про goto мы уже поговорили, а вот теперь поговорим про МАКРОСЫ на пол-страницы


Дык повторно используемый код...
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[5]: Опять про goto
От: Кодт Россия  
Дата: 18.07.06 13:28
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Какое отношение приведенный код имеет к ARM? Архитектурно они обычные risk процессоры, насколько мне помнится. В твоем варианте, как я понимаю, основной упор на отсутствие переходов (хотя неявно они там есть, конечно) — так это машины с VLIW, где этим делом управляет компилятор — см. трансмета, IA64 и эльбрус 3.


Имеет такое отношение, что у этих процессоров есть условное исполнение команды.
http://en.wikipedia.org/wiki/Acorn_RISC_Machine
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[6]: Опять про goto
От: Andrew S Россия http://alchemy-lab.com
Дата: 18.07.06 13:34
Оценка:
AS>>Какое отношение приведенный код имеет к ARM? Архитектурно они обычные risk процессоры, насколько мне помнится. В твоем варианте, как я понимаю, основной упор на отсутствие переходов (хотя неявно они там есть, конечно) — так это машины с VLIW, где этим делом управляет компилятор — см. трансмета, IA64 и эльбрус 3.

К>Имеет такое отношение, что у этих процессоров есть условное исполнение команды.

К>http://en.wikipedia.org/wiki/Acorn_RISC_Machine

Ну и какое отношение этот код имеет к ARM? На уровне компилятора, что if, что && в данном случае безразлично (у if семантика напротив более естественна для тех же addххх — см. тот же пример в википедии). Условное исполнение есть у многих процессоров, безотносительно их архитектуры. Зато я теперь понял, что это за код — это в стиле perl
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: Опять про goto
От: viellsky  
Дата: 18.07.06 14:13
Оценка:
Здравствуйте, Rackshas, Вы писали:

R>goto-ненавистники, как вот такой код

R>
R>void HZ()
R>{
R>    if(!init1()) goto d1;
R>    if(!init2()) goto d2;
R>    if(!init3()) goto d3;

R>d3:
R>    destroy3();
R>d2:
R>    destroy2();
R>d1:
R>    destroy1();
R>}

R>


R>Избавить от goto?


создаем базовый класс:

class Inidestr{
public:
  Inidestr(Inidestr* p):m_pID(p){};

  virtual void destroy() = 0;

  virtual bool init()
  {
    bool b = true;
    if(m_pID){
      b = m_pID->init();
      if(!b){
        m_pID->destroy();
      }
    }
    return b;
  };
private:
  Inidestr* m_pID;
};

далее создаем классы наследники Class1 Class2 Class3, реализующие функции init и destroy
class Class1 : Inidestr
{
  bool init()
  {
    return Inidestr::init() && init1();
  }
  void destroy(){destroy1();}
};
class Class2 : Inidestr
{
  bool init()
  {
    return Inidestr::init() && init2();
  }
  void destroy(){destroy2();}
};
class Class3 : Inidestr
{
  bool init()
  {
    return Inidestr::init() && init3();
  }
  void destroy(){destroy3();}
};

а теперь функция ХЗ будет выглядеть так:
void HZ()
{
  Class1* c1 = new Inidestr(0);
  Class2* c2 = new Inidestr(c1);
  Class3* c3 = new Inidestr(c2);
  if(!c3->init()) c3->destroy();
}

ну как, так запутаннее?
Re: Опять про goto
От: ДимДимыч Украина http://klug.org.ua
Дата: 18.07.06 14:20
Оценка:
Здравствуйте, Rackshas, Вы писали:

R>goto-ненавистники, как вот такой код


Кстати, код видимо такой должен быть:

void HZ()
{
    if(!init1()) goto d1;
    if(!init2()) goto d2;
    if(!init3()) goto d3;

    destroy3();
d3:
    destroy2();
d2:
    destroy1();
d1:
}
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[3]: Опять про goto
От: unreg_flex  
Дата: 20.07.06 09:58
Оценка:
K>Здравствуйте, CreatorCray, Вы писали:

R>>>Избавить от goto?

CC>>Лехко!

Ну раз все так легко, то еще вот этот маленький кусочек тоже переведите, plz!

void f(type1 v1,type1 v2,type1 v3,type1 v4,type1 v5) {
  for(int i=0;i<n1;++i) {
    for(int j=i+1;j<n2;++j) {
      for(int k=j+1;j<n3;++k) {
        if(some_exp1(v1,...,v5,i,j,k)) goto skip1;
      }
      if(some_exp2(v1,...,v5,i,j,k)) goto skip2;
    }
    // some code1
    skip1:
    // some code2
  }
  skip2:
  // some code3
}
Re[4]: Опять про goto
От: Pyromancer  
Дата: 20.07.06 18:30
Оценка: +2 :)
Здравствуйте, unreg_flex, Вы писали:

_>Ну раз все так легко, то еще вот этот маленький кусочек тоже переведите, plz!



Можно тоже разрулить, нужно два булевых флага и пучок ифов и брейков,
только скажите куда этот код пойдёт, неохота потом попасть на работу, где надо будет его поддерживать
Re: Опять про goto
От: Kolhoz Мухосранск  
Дата: 20.07.06 21:18
Оценка:
Здравствуйте, Rackshas, Вы писали:

R>goto-ненавистники, как вот такой код...


Лучше пусть почитают, дурачки, вот это:

http://www.literateprogramming.com/adventure.pdf

Может хотя бы фамилия автора заставит их, дурачков, задуматься.
Re[2]: Опять про goto
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.07.06 05:41
Оценка: +1
Здравствуйте, Kolhoz, Вы писали:
K> Может хотя бы фамилия автора заставит их, дурачков, задуматься.
Может, хотя бы бан на 30 дней заставит тебя задуматься. Рекомендую освободившееся время, которое ты посвящал оскорблениям посетителей RSDN, потратить на изучение обязательных правил.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Опять про goto
От: Дм.Григорьев  
Дата: 21.07.06 20:07
Оценка: -1
Здравствуйте, ДимДимыч, Вы писали:

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

К>>Про goto мы уже поговорили, а вот теперь поговорим про МАКРОСЫ на пол-страницы

ДД>Дык повторно используемый код...


Зачот, однако.
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.