информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Spanning Tree Protocol: недокументированное применениеГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Kik закрывается, все ушли на криптофронт 
 Sophos открывает Sandboxie 
 Большой вторник патчей от MS 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Some details in question… 12.09.11 17:36  Число просмотров: 1985
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Some details in question…
Multiple nested Ifs are always wacky, as well as multiple returns:

There are some ways people usually improve coding:

int func() 
{
   CSomeResource* pResource  = NULL;
   int err = 0;

   err = f1();

   if (!err) {
       err = f2(&pResource);
   }

   if (!err) {
       err = f3(pResource);
   }

   …

   if (!err) {
       err = fn();
   }

   // error handling and freeing resources 
   If (err && pResource) {
       delete pResource;
       pResoruce = NULL;
  }
   
 return (err);
}

---


Another approach is to leverage the WDF idiom:

int func() 
{
   CSomeResource* pResource  = NULL;
   int err = 0;

   do {

      err = f1();
      if (err) {
           break;
      }

      err = f2(&pResource);
      if (err) {
           break;
      }

       err = f3(pResource);
       if (err) {
             break;
        }

   …

       err = fn();
       if (err) {
             break;
        }

   } while (false);

// error handling and freeing resources 

   If (err && pResource) {
       delete pResource;
       pResoruce = NULL;
  }

    return (err);
}

---


What I meant in the initial question is:

int func() 
{
   CSomeResource* pResource  = NULL;
   int err = 0;

      err = f1();
      if (err) {
           goto ErrorHandler;
      }

      err = f2(&pResource);
      if (err) {
           goto ErrorHandler;
      }

       err = f3(pResource);
       if (err) {
           goto ErrorHandler;
        }

   …

       err = fn();
       if (err) {
           goto ErrorHandler;
        }


// error handling and freeing resources 
ErrorHandler:

   If (err && pResource) {
       delete pResource;
       pResoruce = NULL;
  }

    return (err);
}

---


Thanks
<programming>
goto vs do {} while (false) ? 09.09.11 22:06  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
В каком смысле ? 10.09.11 04:47  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Вообще-то использование goto там, где без него можно обойтись - типичный быдлокодинг, но бывают ситуации, например, с множественным входом-выходом из цикла, где без него - никак. Если необходимо получить максимальную компактоность/быстродействие, то goto, так же, предпочтителнее, поскольку do while и break часто генерят лишние переходы.

В общем, не хватает информации.
Существует много ситуаций, где идиома DWF даёт ясный код с... 10.09.11 06:31  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Существует много ситуаций, где идиома DWF даёт ясный код с хорошим мэйтенатсом избавляя от множества запутанных вложенных if, с одной точкой очистки ресурсов и выхода из функции.
Если отбросить преимущества DWF в макросах (что используется не часто), то goto - даёт тоже решение, что и DWF. Макрософт, кажется, это постоянно использует (goto) вместо do {} while (false).
очень даже может быть... 10.09.11 12:49  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
сам частенько использую в методах if () return ... вместо кучи вложенных if и одного return в конце метода, для лучшего чтения кода и уменьшения вложений.
Some details in question… 12.09.11 17:36  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Some details in question…
Multiple nested Ifs are always wacky, as well as multiple returns:

There are some ways people usually improve coding:

int func() 
{
   CSomeResource* pResource  = NULL;
   int err = 0;

   err = f1();

   if (!err) {
       err = f2(&pResource);
   }

   if (!err) {
       err = f3(pResource);
   }

   …

   if (!err) {
       err = fn();
   }

   // error handling and freeing resources 
   If (err && pResource) {
       delete pResource;
       pResoruce = NULL;
  }
   
 return (err);
}

---


Another approach is to leverage the WDF idiom:

int func() 
{
   CSomeResource* pResource  = NULL;
   int err = 0;

   do {

      err = f1();
      if (err) {
           break;
      }

      err = f2(&pResource);
      if (err) {
           break;
      }

       err = f3(pResource);
       if (err) {
             break;
        }

   …

       err = fn();
       if (err) {
             break;
        }

   } while (false);

// error handling and freeing resources 

   If (err && pResource) {
       delete pResource;
       pResoruce = NULL;
  }

    return (err);
}

---


What I meant in the initial question is:

int func() 
{
   CSomeResource* pResource  = NULL;
   int err = 0;

      err = f1();
      if (err) {
           goto ErrorHandler;
      }

      err = f2(&pResource);
      if (err) {
           goto ErrorHandler;
      }

       err = f3(pResource);
       if (err) {
           goto ErrorHandler;
        }

   …

       err = fn();
       if (err) {
           goto ErrorHandler;
        }


// error handling and freeing resources 
ErrorHandler:

   If (err && pResource) {
       delete pResource;
       pResoruce = NULL;
  }

    return (err);
}

---


Thanks
по мне, лучше так: 12.09.11 20:08  
Автор: Den <Denis> Статус: The Elderman
Отредактировано 12.09.11 20:11  Количество правок: 2
<"чистая" ссылка>
int func() 
{
    CSomeResource* pResource  = NULL;
    int err = 0;

    err = f1();
    if (err) {
        return (err);
    }

    err = f2(&pResource);
    if (err) {
        ReleaseResources(&pResource);
        return (err);
    }

    err = f3(pResource);
    if (err) {
        ReleaseResources(&pResource);
        return (err);
    }

   . . .

    err = fn();
    if (err) return (err);

   . . .

    return (err);
}

void ReleaseResources (CSomeResource* pRes) {
       if (pRes) delete pRes;
       pRes = NULL;
       return;
}

---
What if you need to work with more than 1 resource? For... 12.09.11 21:33  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
What if you need to work with more than 1 resource? For instance, create a socket, allocate a buffer, open a file, and so on. You will probably need to release all of them in each IF?
Why not? In each IF I'll release all resources by invoke separate functions. 12.09.11 22:17  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
Sure it works. But it is easy to make a mistake. Is not it... 12.09.11 23:26  
Автор: void <Grebnev Valery> Статус: Elderman
<"чистая" ссылка>
Sure it works. But it is easy to make a mistake. Is not it better to have just one point at the function code where all the resources are released?
Вот тут-то, как раз и получается тот самый "конечный автомат с запомининием..." 13.09.11 00:46  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Поскольку возврат из подпрограммы-обработчика ошибки получается в ту же точку. Плюс (точнее - минус) затраты ресурсов на вызов-возврат.
по твоему, зачем в качестве значения функции возвращается код ошибки? 13.09.11 01:22  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
А почему возвращается ф-цией? 14.09.11 04:44  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Это же не ядро оси, где все ошибки генерятся софтом и другого способа их диагностики быть не может. У робота ошибки обусловлены непредсказуемыми внешними условиями, диагнстика малоинформативна, а действия по устранению ошибки и продолжению работы - чистая эвристика наладчиков.

Тут смысл, именно, в возможности перехода в ручное управление вплоть до гаечного ключа и возможности таким способом выйти в любую стадию, с которо и продолжить работу. Ф-ция с фиксированной точкой входа/выхода здесь не катит, нужна, именно, возможность возврата из ручного режима в любую точку. Или, как во 2й моей задаче - всегда в нулевую, поскольку шагов очень много и проще после сбоя рестартовать с нуля, задав уже выполненные операции, как начальные условия.

Я тут уже 3 библиотечных модуля родил, вы будете смеяться, но у Сименса их нет! "Вертушки":
-шаговый искатель,
-мультистабильный триггер (сколько выходов, столько и установочных входов, порядок - произвольный)
-последовательный мультистабильный триггер (то же самое, то N+1 состояние может включиться только после N-ного)

Во 2м и 3м случаях на N+1вход подаются контроли готовности после выполнения N-ного шага.
примитив ) 14.09.11 15:00  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
В таких делах, что примитивно - то и эффективно. 15.09.11 16:44  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Во-первых - минимальные ресурсы и максимальное быстродействие, во-вторых - а для кого стараться? Модернизироваться-то основные циклы работы не будут, потому вопрос понятности для последователей не стоит. А вот для меня самого такой подход наиболее прозрачен, поскольку похож на "железяку".
согласен 15.09.11 16:50  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка>
но меня всегда тошнило от программирования роботов )
Каждому - свое. Я всю жизнь занимаюсь, именно этим. 16.09.11 04:01  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
и лучше всего все понимаю, именно, "от железа".
Ну, вот у меня на столе сейчас задачка - цикл работы робота,... 11.09.11 04:10  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Ну, вот у меня на столе сейчас задачка - цикл работы робота, где без goto - никак. На любом шаге может возникнуть отказ, при котором после истечения контрольного времени операции переход в ручной режим. В ручном неисправность устраняется, после чегоробот кнопками и гаечным ключом выгоняется в ближайшую позицию и вручную передается управление внутрь цикла в эту самую позицию.

И как это сделать без goto из цикла и в цикл?
конечный автомат с запоминанием последнего рабочего состояния при переходе на устранение неисправности 11.09.11 10:48  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
Нет, вот, как раз запоминания последнего состояния мне и надо здесь избежать 12.09.11 03:39  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка>
Потому, как покореженную заготовку убрали, а он все еще думает, что она там и пока все положенные операции с пустым местом не закончит - не остановится. Т.е. в идеале он после устранения неисправности вручную выводится в ближайшую подходящую позицию и оттуда рестартует.
ну как бы необязательно возвращаться строго в то состояние, которое запомнилось 12.09.11 15:51  
Автор: dl <Dmitry Leonov>
<"чистая" ссылка>
Достаточно его учитывать, это уже по ситуации. Конечно, можно и сами конечные автоматы считать очень завуалированным goto, но всякие вещи со сменой состояний с ними пишутся гораздо приятней.
1  |  2 >>  »  






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2019 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach