Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | | |
Some details in question… 12.09.11 17:36 Число просмотров: 2966
Автор: 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 <Денис Т.> Статус: 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 <Денис Т.> Статус: 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 <Денис Т.> Статус: 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 <Денис Т.> Статус: 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 <Денис Т.> Статус: The Elderman
|
|
| | | | | | | | | | | | |
В таких делах, что примитивно - то и эффективно. 15.09.11 16:44
Автор: Zef <Alloo Zef> Статус: Elderman
|
Во-первых - минимальные ресурсы и максимальное быстродействие, во-вторых - а для кого стараться? Модернизироваться-то основные циклы работы не будут, потому вопрос понятности для последователей не стоит. А вот для меня самого такой подход наиболее прозрачен, поскольку похож на "железяку".
|
| | | | | | | | | | | | | |
согласен 15.09.11 16:50
Автор: Den <Денис Т.> Статус: 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, но всякие вещи со сменой состояний с ними пишутся гораздо приятней.
|
|
|