Приходилось ли вам использовать goto?
От: zzzale  
Дата: 31.03.06 08:07
Оценка:
Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).
Интересуют прежде всего языки С++,С#.
Re: Приходилось ли вам использовать goto?
От: Вумудщзук Беларусь  
Дата: 31.03.06 09:13
Оценка:
>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).
>Интересуют прежде всего языки С++,С#.
Когда учил с++ — да

в проектах на работе — нет... может, ещё опыта маловато ?
Homo sum et nihil humani a me alienum puto...
Re: Приходилось ли вам использовать goto?
От: Cyberax Марс  
Дата: 31.03.06 09:40
Оценка:
zzzale wrote:
> Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять
> этот оператор (желательно с примером и описанием ПО).
В "Этюдах" как раз недавно был пример.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re: Приходилось ли вам использовать goto?
От: Kemsky  
Дата: 31.03.06 09:56
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).

Z>Интересуют прежде всего языки С++,С#.

А что значит "ДЕЙСТВИТЕЛЬНО"? Я goto применяю довольно часто. Однако если исходить из того, что добавление к коду лишней bool переменной и её проверка — меньшее зло, чем goto, то примера, собственно, привести и не получится
Re[2]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.03.06 10:01
Оценка:
Здравствуйте, Kemsky, Вы писали:

K>А что значит "ДЕЙСТВИТЕЛЬНО"? Я goto применяю довольно часто. Однако если исходить из того, что добавление к коду лишней bool переменной и её проверка — меньшее зло, чем goto, то примера, собственно, привести и не получится


А Вы, пожалуйста, приведите какой-нибудь (канонический) пример в котором устранение goto с неизбежностью повлечёт введение лишнего булевского флага(ов).
Re[3]: Приходилось ли вам использовать goto?
От: Нахлобуч Великобритания https://hglabhq.com
Дата: 31.03.06 10:05
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>А Вы, пожалуйста, приведите какой-нибудь (канонический) пример в котором устранение goto с неизбежностью повлечёт введение лишнего булевского флага(ов).


Выйти из двух циклов разом?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
HgLab: Mercurial Server and Repository Management for Windows
Re[4]: Приходилось ли вам использовать goto?
От: Cider Россия  
Дата: 31.03.06 10:33
Оценка: -1
Здравствуйте, Нахлобуч, Вы писали:

Н>Здравствуйте, Сергей Губанов, Вы писали:


СГ>>А Вы, пожалуйста, приведите какой-нибудь (канонический) пример в котором устранение goto с неизбежностью повлечёт введение лишнего булевского флага(ов).


Н>Выйти из двух циклов разом?


Неизбежности нет. Например, оператор break (не помню, есть ли в плюсах break на метку). Так же можно эти циклы вынести в отдельную функцию и выходить уже из нее. Можно бросить исключение. Так что вариантов в данном случае много.
Cider
Re[5]: Приходилось ли вам использовать goto?
От: Cyberax Марс  
Дата: 31.03.06 10:37
Оценка:
Cider wrote:
> Неизбежности нет. Например, оператор break (не помню, есть ли в плюсах
> break на метку). Так же можно эти циклы вынести в отдельную функцию и
> выходить уже из нее. Можно бросить исключение. Так что вариантов в
> данном случае много.
Это просто аналоги goto.

Некоторые (не будем показывать пальцами) тут вообще считают, что
break/continue не нужны
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[5]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 31.03.06 10:47
Оценка: +1
Здравствуйте, Cider, Вы писали:

СГ>>>А Вы, пожалуйста, приведите какой-нибудь (канонический) пример в котором устранение goto с неизбежностью повлечёт введение лишнего булевского флага(ов).


Н>>Выйти из двух циклов разом?


C>Неизбежности нет. Например, оператор break (не помню, есть ли в плюсах break на метку). Так же можно эти циклы вынести в отдельную функцию и выходить уже из нее. Можно бросить исключение. Так что вариантов в данном случае много.


В отдельную функцию — увы, создавать структуру с 10 переменными и копировать её туда-сюда, или передавать по ссылке их все. В С++ как назло нет ни локальных функций, ни замыканий, чтобы в этом помочь.

Исключение — это ИСКЛЮЧЕНИЕ. Не надо их использовать для обычных ситуаций.

Предлагаю поупражняться:
        CString expr = m_settings.expr;
        while (1)
        {
            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
            for (size_t i = 0; i < m_settings.rules.size(); ++i)
            {
                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
                {
                    MessageBox("Syntax error", 0, 0);
                    goto the_goto;
                }
            }
            break;
the_goto:;
        }
        m_settings.expr = expr;


Смысл — отредактировать строку с помощью диалога-редактора, но оно должно пройти все правила. Если введено неправильная строка, диалог редактирования должен остаться. Вариантов можно придумать много, вот и давайте выберем наилучший
Re[6]: Приходилось ли вам использовать goto?
От: Cider Россия  
Дата: 31.03.06 10:51
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Cider wrote:

>> Неизбежности нет. Например, оператор break (не помню, есть ли в плюсах
>> break на метку). Так же можно эти циклы вынести в отдельную функцию и
>> выходить уже из нее. Можно бросить исключение. Так что вариантов в
>> данном случае много.

C>Это просто аналоги goto.


Тогда все операции изменения потока управления — это аналог goto
Cider
Re[7]: Приходилось ли вам использовать goto?
От: Cyberax Марс  
Дата: 31.03.06 10:56
Оценка:
Cider wrote:
>> > Неизбежности нет. Например, оператор break (не помню, есть ли в плюсах
>> > break на метку). Так же можно эти циклы вынести в отдельную функцию и
>> > выходить уже из нее. Можно бросить исключение. Так что вариантов в
>> > данном случае много.
> C>Это просто аналоги goto.
> Тогда все операции изменения потока управления — это аналог goto
Примерно так и есть.

Но вот while/for-циклы в отсутствии break/continue отличаются тем, что
имеют пост- и пред- условия.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[6]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.03.06 11:01
Оценка: -2
Здравствуйте, Cyberax, Вы писали:

C>Некоторые (не будем показывать пальцами) тут вообще считают, что

C>break/continue не нужны

Continue — не нужны вообще, а break не должны быть внутри WHILE-DO-END и REPEAT-UNTIL циклах по определению этих циклов (иначе эти циклы в принципе нельзя будет называть WHILE-DO-END и REPEAT-UNTIL циклами). В языке Oberon кроме WHILE-DO-END и REPEAT-UNTIL циклов есть безусловный цикл LOOP-END, вот внутри него break есть (только называется не break, а EXIT). Кстати, с помощью этого EXIT частично решается вопрос выхода из нескольких вложенных циклов.
...
...
LOOP
  ...
  ...
  WHILE a DO
    ...
    ...
    REPEAT
      ...
      ...
      FOR i := 0 TO N DO
        ...
        ...
        IF b THEN EXIT END; (* EXIT - это выход из цикла LOOP *)
        ...
        ...
        IF c THEN RETURN END; (* просто выход из процедуры *)
        ...
        ...
      END;
      ...
      ...
    UNTIL d;
    ...
    ...  
  END;
  ...
  ...
END;
...
...
Re[6]: Приходилось ли вам использовать goto?
От: Cider Россия  
Дата: 31.03.06 11:05
Оценка: +1
Здравствуйте, Кодёнок, Вы писали:

Кё>В отдельную функцию — увы, создавать структуру с 10 переменными и копировать её туда-сюда, или передавать по ссылке их все. В С++ как назло нет ни локальных функций, ни замыканий, чтобы в этом помочь.


А чем плохо передать ссылку на структуру? Ну, жираф большой, ему видней.

Кё>Исключение — это ИСКЛЮЧЕНИЕ. Не надо их использовать для обычных ситуаций.


А никто и не говорит, что ситуация обычная.

Кё>Предлагаю поупражняться:


В плюсах не силен, потому напишу на псевдо-коде (сильно пахнущем явой ).
...
        do {
            str = MyMegaDialog.doModal();
        } while (!check(str));

...

    boolean check(String str) {
    // судя по имени, m_settings - это поле, поэтому передавать не нужно
        for (size_t i = 0; i < m_settings.rules.size(); ++i)
        {
            if (m_settings.rules[i].active && !m_settings.rules[i].Check(str)) 
            {
                MessageBox("Syntax error", 0, 0);
                return false;
            }
        }
        m_settings.expr = str;
        return true;
    }


А еще лучше, функциональность проверки внес бы внутрь этого m_settings или выделил бы в отдельный класс.
Cider
Re[6]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.03.06 11:20
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Предлагаю поупражняться:

Кё>
Кё>        CString expr = m_settings.expr;
Кё>        while (1)
Кё>        {
Кё>            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
Кё>            for (size_t i = 0; i < m_settings.rules.size(); ++i)
Кё>            {
Кё>                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
Кё>                {
Кё>                    MessageBox("Syntax error", 0, 0);
Кё>                    goto the_goto;
Кё>                }
Кё>            }
Кё>            break;
Кё>the_goto:;
Кё>        }
Кё>        m_settings.expr = expr;
Кё>


Извиняюсь за иной язык и за изменение обозначений:
LOOP
  IF DialogShowModal(expr) # ok THEN RETURN 0 END;
  i := 0;
  WHILE (i < size) & ~(rules[i].active & ~rules[i].Check(expr)) DO INC(i) END;
  IF i = size THEN EXIT END; (* EXIT - это в Oberon инструкция выхода из цикла LOOP *)
  ShowErrorBox("Ошибка в правиле номер i = ", i, 0, 0)
END
Re[7]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 31.03.06 11:57
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Извиняюсь за иной язык и за изменение обозначений:

СГ>LOOP
СГ> IF DialogShowModal(expr) # ok THEN RETURN 0 END;
СГ> i := 0;
СГ> WHILE (i < size) & ~(rules[i].active & ~rules[i].Check(expr)) DO INC(i) END;
СГ> IF i = size THEN EXIT END; (* EXIT — это в Oberon инструкция выхода из цикла LOOP *)
СГ> ShowErrorBox("Ошибка в правиле номер i = ", i, 0, 0)
СГ>END

Вообще интересно выкрутился, только тут ошибка, i = size неверно, надо i = numberOfActiveRules, т.е. надо завести вторую переменную для подсчета кол-ва включенных правил. Получается решение, аналогичное введению булевого флага.
Re[3]: Приходилось ли вам использовать goto?
От: Kemsky  
Дата: 31.03.06 12:07
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Здравствуйте, Kemsky, Вы писали:


K>>А что значит "ДЕЙСТВИТЕЛЬНО"? Я goto применяю довольно часто. Однако если исходить из того, что добавление к коду лишней bool переменной и её проверка — меньшее зло, чем goto, то примера, собственно, привести и не получится


СГ>А Вы, пожалуйста, приведите какой-нибудь (канонический) пример в котором устранение goto с неизбежностью повлечёт введение лишнего булевского флага(ов).


Нет такого примера. Для избавления от goto можно также использовать дублирование кода (или помещение этого самого дублирующегося кода в отдельную функцию), continue и break с циклами (смысл которых лишь в том, чтобы не использовать goto), switch, throw. Мощь этих средств столь велика, что всегда можно обойтись и без goto, и без булевского флага.
Впрочем, если угодно, канонический пример, где я обычно использую goto:

{
if( <усл1> )
<действ1>
else if( <усл2> )
<действ2>
else goto exit;
<действ3>
exit:;
}
Re[7]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 31.03.06 12:07
Оценка:
Здравствуйте, Cider, Вы писали:

Кё>>Предлагаю поупражняться:


C> boolean check(String str) {


C>А еще лучше, функциональность проверки внес бы внутрь этого m_settings или выделил бы в отдельный класс.


Вот если бы в плюсах можно быть сделать этот check локальной функцией, это было бы хорошее решение И код бы стал читабельнее.

А так приходится на уровень выше, туда, где эта вспомогательная функция вообще никому не нужна Первая проблема, это то, что ей придётся дать конкретное осмысленное имя — в контексте функции редактирования "check" идеально подходит, в контексте интерфейса класса — конфликтует с уже имеющейся или непонятно что означает. Вторая проблема в том, что унести её в private — значит, сильно удалить от основной, в public она не нужна, а сделать private только её (как в C# — private bool check(){}) в С++ нельзя.
Re[8]: Приходилось ли вам использовать goto?
От: Cider Россия  
Дата: 31.03.06 12:11
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Вот если бы в плюсах можно быть сделать этот check локальной функцией, это было бы хорошее решение И код бы стал читабельнее.


Кё>А так приходится на уровень выше, туда, где эта вспомогательная функция вообще никому не нужна Первая проблема, это то, что ей придётся дать конкретное осмысленное имя — в контексте функции редактирования "check" идеально подходит, в контексте интерфейса класса — конфликтует с уже имеющейся или непонятно что означает. Вторая проблема в том, что унести её в private — значит, сильно удалить от основной, в public она не нужна, а сделать private только её (как в C# — private bool check(){}) в С++ нельзя.


Так кто мешает соорудить небольшой классец, даже внутренний, назвать его ExpressionChecker и засунуть всю эту функциональность в него?
Тогда и имена будут звучать логично, и код будет выглядеть понятно.
Cider
Re[8]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.03.06 12:24
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Вообще интересно выкрутился, только тут ошибка, i = size неверно, надо i = numberOfActiveRules, т.е. надо завести вторую переменную для подсчета кол-ва включенных правил. Получается решение, аналогичное введению булевого флага.


Правило считается (делается инкремент INC(i)) не зависимо о того активно оно или не активно:

i := 0;
WHILE (i < LEN(rules)) & ~(rules[i].active & ~rules[i].Check(expr)) DO INC(i) END;
IF i = LEN(rules) THEN EXIT END;

просто если оно не активно, то Check(expr) — не производится (потому что инструкция "a & b" выполняется слева направо и если её результат становится уже известным (т.е. если a = FALSE), то вычисление b не производится).

Короче, мне кажется, что ошибки нет...
Re[6]: Приходилось ли вам использовать goto?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 31.03.06 12:26
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Предлагаю поупражняться:

Кё>
Кё>        CString expr = m_settings.expr;
Кё>        while (1)
Кё>        {
Кё>            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
Кё>            for (size_t i = 0; i < m_settings.rules.size(); ++i)
Кё>            {
Кё>                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
Кё>                {
Кё>                    MessageBox("Syntax error", 0, 0);
Кё>                    goto the_goto;
Кё>                }
Кё>            }
Кё>            break;
Кё>the_goto:;
Кё>        }
Кё>        m_settings.expr = expr;
Кё>


namespace {

struct ExpressionCheckerAndSetter {
  SomeSettings & m_setting;
  ExpressionChecker( SomeSettings & setting ) : m_setting( setting ) {}

  bool operator()( const CString & expr )
  {
    for( size_t i = 0, i_max = m_settings.rules.size(); i != i_max; ++i )
      if( m_settings.rules[ i ].active && !m_settings.rules[ i ].Check( expr ) )
      {
        MessageBox( "Syntax error", 0, 0 );
        return false;
      }
    m_settings.expr = expr;
    return true;
  }
};

}

...
ExpressionCheckerAndSetter checker( m_setting );
CString expr = m_settings;
do {
  if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
} while( !checker( expr ) );


Кстати, если не ошибаюсь, ExpressionCheckerAndSetter можно объявить и внутри самой функции.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 31.03.06 12:38
Оценка:
Здравствуйте, eao197, Вы писали:

E>struct ExpressionCheckerAndSetter {

E> SomeSettings & m_setting;
E> ExpressionChecker( SomeSettings & setting ) : m_setting( setting ) {}

E>Кстати, если не ошибаюсь, ExpressionCheckerAndSetter можно объявить и внутри самой функции.


Классический шаблон эмуляции замыканий в С++? Я не спорю, что есть 33 разных способа избавиться от goto. Меня интересует способы, которые не хуже — не больше кода, или чуть больше, но понятней.

Вот Сергею Губанову удалось сделать код короче...
Re[8]: Приходилось ли вам использовать goto?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 31.03.06 12:49
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Классический шаблон эмуляции замыканий в С++?


Очень похоже на очередную попытку сказать "Нет! Это я ненавижу C++ больше всех!!!"

Ке> Я не спорю, что есть 33 разных способа избавиться от goto. Меня интересует способы, которые не хуже — не больше кода, или чуть больше, но понятней.


Может объяснишь, чем мой код хуже, особенно с учетом вот этого:

А так приходится на уровень выше, туда, где эта вспомогательная функция вообще никому не нужна Первая проблема, это то, что ей придётся дать конкретное осмысленное имя — в контексте функции редактирования "check" идеально подходит, в контексте интерфейса класса — конфликтует с уже имеющейся или непонятно что означает. Вторая проблема в том, что унести её в private — значит, сильно удалить от основной, в public она не нужна, а сделать private только её (как в C# — private bool check(){}) в С++ нельзя.




SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 31.03.06 12:56
Оценка:
Здравствуйте, eao197, Вы писали:

E>Может объяснишь, чем мой код хуже, особенно с учетом вот этого:

Кё>А так приходится на уровень выше, туда, где эта вспомогательная функция вообще никому не нужна Первая проблема, это то, что ей придётся дать конкретное осмысленное имя — в контексте функции редактирования "check" идеально подходит, в контексте интерфейса класса — конфликтует с уже имеющейся или непонятно что означает. Вторая проблема в том, что унести её в private — значит, сильно удалить от основной, в public она не нужна, а сделать private только её (как в C# — private bool check(){}) в С++ нельзя.

E>


Не хуже... В оригинале, всё что нужно сделать, делается именно в том месте, где оно необходимо. У тебя тоже, но длиннее, зато goto нет. Что лучше — вопрос споров я выбираю то, что короче.
Re[6]: Приходилось ли вам использовать goto?
От: Kluev  
Дата: 31.03.06 13:10
Оценка:
Здравствуйте, Кодёнок, Вы писали:


Кё>Предлагаю поупражняться:


    CString expr = m_settings.expr;
    if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
    
    for (int i = 0; i < m_settings.rules.size(); ++i)
    {
        if (!m_settings.rules[i].active || m_settings.rules[i].Check(expr))
            continue;
        MessageBox("Syntax error", 0, 0);
        i = -1; // reset loop
        if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
    }
    m_settings.expr = expr;
Re[10]: Приходилось ли вам использовать goto?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 31.03.06 13:20
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Не хуже... В оригинале, всё что нужно сделать, делается именно в том месте, где оно необходимо. У тебя тоже, но длиннее, зато goto нет. Что лучше — вопрос споров я выбираю то, что короче.


Ну уж раз мосье такой любитель смешивать разную функциональность в одном месте , то:
CString expr = m_settings.expr;
        size_t i, i_max = m_settings.rules.size();
        do
        {
            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
            for ( i = 0; i != i_max ; ++i)
            {
                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
                {
                    MessageBox("Syntax error", 0, 0);
                    break;
                }
            }
        } while( i != i_max );
        m_settings.expr = expr;


Практически твой вариант.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Приходилось ли вам использовать goto?
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 31.03.06 13:28
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Некоторые (не будем показывать пальцами) тут вообще считают, что

C>break/continue не нужны

Ну, насчет break'а вполне можно согласиться. Я его тоже слегка недолюбливаю (чисто иррационально) и частенько пользуюсь конструкцией а-ля:

for (int i = 0; i < 10; ++i)
{
...
    if (some_rare_contition)
    {
        i = 10;        // неявный break :)
    }
    else {
        ...
    }
}
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[7]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 31.03.06 13:29
Оценка: :)
Здравствуйте, Kluev, Вы писали:

А интересная мысль

    CString expr = m_settings.expr;
    for (int i = -1; i < m_settings.rules.size(); ++i)
    {
        if (i < 0)
        {
           if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
        }
        else
        {
          if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
          {
            MessageBox("Syntax error", 0, 0);
            i = -1; // reset loop
          }
        }
    }
    m_settings.expr = expr;
Re[8]: Приходилось ли вам использовать goto?
От: Kluev  
Дата: 31.03.06 13:32
Оценка: 1 (1)
Здравствуйте, Кодёнок, Вы писали:

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


Кё>А интересная мысль


Кё>
Кё>    CString expr = m_settings.expr;
Кё>    for (int i = -1; i < m_settings.rules.size(); ++i)
Кё>    {
Кё>        if (i < 0)
Кё>        {
Кё>           if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
Кё>        }
Кё>        else
Кё>        {
Кё>          if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
Кё>          {
Кё>            MessageBox("Syntax error", 0, 0);
Кё>            i = -2; // reset loop to -1
Кё>          }
Кё>        }
Кё>    }
Кё>    m_settings.expr = expr;
Кё>
Re[4]: Приходилось ли вам использовать goto?
От: IT Россия linq2db.com
Дата: 31.03.06 13:36
Оценка: +1
Здравствуйте, Нахлобуч, Вы писали:

СГ>>А Вы, пожалуйста, приведите какой-нибудь (канонический) пример в котором устранение goto с неизбежностью повлечёт введение лишнего булевского флага(ов).


Н>Выйти из двух циклов разом?


Не надо опять начинать, в прошлый раз всё закончилось вот этим.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Приходилось ли вам использовать goto?
От: Kemsky  
Дата: 31.03.06 13:39
Оценка: +3
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Ну, насчет break'а вполне можно согласиться. Я его тоже слегка недолюбливаю (чисто иррационально) и частенько пользуюсь конструкцией а-ля:


SDB>
SDB>for (int i = 0; i < 10; ++i)
SDB>{
SDB>...
SDB>    if (some_rare_contition)
SDB>    {
SDB>        i = 10;        // неявный break :)
SDB>    }
SDB>    else {
SDB>        ...
SDB>    }
SDB>}
SDB>


Один из аргументов против goto — то, что код с goto менее понятен, чем без. ИМХО в данном примере понятность по сравнению с break несколько уменьшается.
Re[9]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.03.06 13:41
Оценка: :)
> i = -2; // reset loop to -1

Извращенцы
Re[8]: Приходилось ли вам использовать goto?
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 31.03.06 13:46
Оценка:
Здравствуйте, Kemsky, Вы писали:

K>ИМХО в данном примере понятность по сравнению с break несколько уменьшается.


Ну, во-первых, я в таких местах всегда пишу комментарий типа "exit the loop", а во-вторых — как я писал это чисто иррациональное, а не мотивированное большей читабельностью кода. Ну вот заскок у меня такой. Просто иногда бывает "не в тему" заводить очередную булеву переменную, значение которой проверяется наряду с "основным" условием цикла.

P.S.
Посто мой был собственно в поддержку "некоторых", на которых ссылался Cyberax.
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[10]: Приходилось ли вам использовать goto?
От: Kluev  
Дата: 31.03.06 13:55
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

>> i = -2; // reset loop to -1


СГ>Извращенцы


Спокойствие, брат
Спешал фо Ю:
    CString expr = m_settings.expr;
    if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
    
    for (int i = 0; i < m_settings.rules.size(); )
    {
        if (!m_settings.rules[i].active || m_settings.rules[i].Check(expr))
        {
            ++i;
            continue;
        }
        MessageBox("Syntax error", 0, 0);
      i = 0; // reset loop to zero
        if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
    }
    m_settings.expr = expr;
Re: Приходилось ли вам использовать goto?
От: yurafitt  
Дата: 31.03.06 16:48
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).

Z>Интересуют прежде всего языки С++,С#.
Мне нет, а вот в примерах поставляемых с SDK DirectX 7.0 во многих местатх встречал использование goto
Re[7]: Приходилось ли вам использовать goto?
От: kan_izh Великобритания  
Дата: 31.03.06 17:46
Оценка:
SchweinDeBurg wrote:

> Ну, насчет break'а вполне можно согласиться. Я его тоже слегка

> недолюбливаю (чисто иррационально) и частенько пользуюсь конструкцией а-ля:
>
> for (int i = 0; i < 10; ++i)
> {
> ...
> if (/some_rare_contition/)
> {
> i = 10; // неявный break
> }
> else {
> ...
> }
> }
Ну это довольно редко встречается, когда по числам итерируется. А в таком случае как? Или для разных случаев по-разному
из цикла выходить?? Нет уж, увольте.
for(map<???>::const_iterator i=m.begin(); i!=m.end(); ++i)
{
    if(needskip1(*i)) continue;
    if(needskip2(*i)) continue;
    if(needskip3(*i)) continue;
    makesomething(*i);
    if(blah(*i)) break;
    makeotherthing(*i);
}

или

for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
{
    if(c->type == NODE_TEXT) continue;
    if(c->namespace != myNamespace) continue;
...
}

В таком коде такой неявный брэйк нельзя сделать. А замена несколько continue будет порождать глубокую вложенность if.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Приходилось ли вам использовать goto?
От: kan_izh Великобритания  
Дата: 31.03.06 18:09
Оценка:
Кодёнок wrote:

> Смысл — отредактировать строку с помощью диалога-редактора, но оно

> должно пройти все правила. Если введено неправильная строка, диалог
> редактирования должен остаться. Вариантов можно придумать много, вот и
> давайте выберем наилучший
Я подобные вещи обычно так пишу.
И сразу отсюда становится видно, что hasErrors легко выносится в функцию. И я обычно выношу, особенно если подобный код
встречается более одного раза.
while(1)
{
    if (IDOK != DataEditorDialog(expr).DoModal()) return 0;

    bool hasErrors = false;
    for (size_t i = 0; i < m_settings.rules.size(); ++i)
    {
        if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
        {
            hasErrors = true;
            break;
        }
    }

    if(hasErrors)
        MessageBox("Syntax error", 0, 0);
    else
        break;
}



А ещё можно написать предикат проверки правила воспользоватья find из stl, но это уже неинтересно.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[8]: Приходилось ли вам использовать goto?
От: McSeem2 США http://www.antigrain.com
Дата: 31.03.06 18:14
Оценка: +3 :)))
Здравствуйте, Kemsky, Вы писали:

K>Один из аргументов против goto — то, что код с goto менее понятен, чем без. ИМХО в данном примере понятность по сравнению с break несколько уменьшается.


Я бы сказал, что использование goto в стиле Фортрана-4 — это маразм. Однако, полный запрет goto — это тоже маразм. Народу не нужен нездоровый фанатизм. Народу нужен здоровый фанатизм.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[6]: Приходилось ли вам использовать goto?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.03.06 21:17
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Предлагаю поупражняться:


string expr = _settings.Expr;
using (DataEditorDialog ded = new DataEditorDialog())
{
    ded.Closing += (sender, e) =>
    {
        if (DialogResult == DialogResult.OK)
        {
            foreach (Rule r in _settings.Rules)
                if (r.Active && !r.Check(expr))
                {
                    e.Cancel = true;
                    return;
                }
            _settings.Expr = ded.Expr;
        }
    }
    ded.ShowDialog();    
}


Пойдет?
... << RSDN@Home 1.2.0 alpha rev. 646 on Windows XP 5.1.2600.131072>>
AVK Blog
Re[7]: Приходилось ли вам использовать goto?
От: Ziaw Россия  
Дата: 01.04.06 05:26
Оценка: +1
AVK>
AVK>string expr = _settings.Expr;
AVK>using (DataEditorDialog ded = new DataEditorDialog())
AVK>{
AVK>    ded.Closing += (sender, e) =>
AVK>    {
AVK>        if (DialogResult == DialogResult.OK)
AVK>        {
AVK>            foreach (Rule r in _settings.Rules)
AVK>                if (r.Active && !r.Check(expr))
AVK>                {
AVK>                    e.Cancel = true;
AVK>                    return;
AVK>                }
AVK>            _settings.Expr = ded.Expr;
AVK>        }
AVK>    }
AVK>    ded.ShowDialog();    
AVK>}
AVK>


Как раз хотел написать, что плохой код и плохое юзабилити часто ходят рядом.
В предыдущем примере налицо неважное юзабилити: диалог гаснет, вываливается
синтакс еррор, потом тут же как черт из табакерки вываливается пустой новый диалог "попробуй-ка еще раз, дружок". Даже не глядя на код становится понятно, что проверку надо делать не закрывая диалог ввода. Отличное решение, легко дополняется диагностикой проблемы, но даже без нее введенная строка видна и можно самому локализовать ее.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Re: Приходилось ли вам использовать goto?
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.04.06 00:45
Оценка: +1
Здравствуйте, zzzale, Вы писали:

Z>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).

Z>Интересуют прежде всего языки С++,С#.

А болкк интеллектуальных вопросов не нашлось?

Или новое поколени РСДН-еров не умеет пользоваться поиском?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Приходилось ли вам использовать goto?
От: vdimas Россия  
Дата: 02.04.06 00:48
Оценка:
Здравствуйте, Cider, Вы писали:

C>Тогда все операции изменения потока управления — это аналог goto


Не все, а только лишь безусловные.

Для С-подобных языков, это: goto, return, break, continue.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: Приходилось ли вам использовать goto?
От: Kemsky  
Дата: 03.04.06 06:48
Оценка: :)))
Здравствуйте, McSeem2, Вы писали:

MS>Я бы сказал, что использование goto в стиле Фортрана-4 — это маразм. Однако, полный запрет goto — это тоже маразм. Народу не нужен нездоровый фанатизм. Народу нужен здоровый фанатизм.


Вы подходите к вопросу слишком рационально. Между тем, если изучить постинги по этому вопросу, станет очевидным, что с этим оператором дело не чисто. Он скверен, как число 13, как представитель касты неприкасаемых. Его использование — это ересь, за которую следует отлучать от интернета.
Re[8]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 03.04.06 07:45
Оценка:
Здравствуйте, kan_izh, Вы писали:

_>for(xmlNodePtr c = parent->children; c; c = c->nextSibling)

_>{
_> if(c->type == NODE_TEXT) continue;
_> if(c->namespace != myNamespace) continue;
_>...
_>}
_>[/ccode]
_>В таком коде такой неявный брэйк нельзя сделать. А замена несколько continue будет порождать глубокую вложенность if.

По моему, даже самая наиглубочайшая вложенность IF — и то лучше чем один единственный continue по той простой причине, что код содержащий в себе слова continue невозможно оформить в виде отдельной процедуры.

Кстати, зачастую, всё множество вложенных IF-ов можно заменить одним единственным:
for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
{
  if ((c->type != NODE_TEXT) && (c->namespace == myNamespace) && (...) && (...) && (...) && (...) ...)
  {
    ...
  }
}

или ещё лучше так:
for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
{
  if (IsThisGood(c))
  {
    ...
  }
}
Re[9]: Приходилось ли вам использовать goto?
От: kan_izh Великобритания  
Дата: 03.04.06 09:59
Оценка:
Сергей Губанов wrote:

> _>for(xmlNodePtr c = parent->children; c; c = c->nextSibling)

> _>{
> _> if(c->type == NODE_TEXT) continue;
> _> if(c->namespace != myNamespace) continue;
> _>...
> _>}
> _>[/ccode]
> _>В таком коде такой неявный брэйк нельзя сделать. А замена несколько
> continue будет порождать глубокую вложенность if.
>
> По моему, даже самая наиглубочайшая вложенность IF — и то лучше чем один
> единственный continue по той простой причине, что код содержащий в себе
> слова continue невозможно оформить в виде отдельной процедуры.
Вообще говоря, различие исключительно синтаксическое, continue — всего лишь sugar, насколько оправдано использование
сахара — не знаю, диабетикам, конечно, вредно, но это не означает, что его нужно запретить вообще.
Так что почему невозможно? Не сложнее, чем куча вложенных if-ов. И делается довольно просто — все continue заменяются на
"return false", в конце, где нет continue — return true, а вместо блока, содержащего continue-ы ставим
if(!checkContinues(i)) continue;
или
if(chechContinues(i))
{
...
}

по вкусу.

> Кстати, зачастую, всё множество вложенных IF-ов можно заменить одним

> единственным:
>
> for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
> {
> if ((c->type != NODE_TEXT) && (c->namespace == myNamespace) && (...) && (...) && (...) && (...) ...)
> {
> ...
> }
> }
>
Насколько оправданно писать всё в одну строчку (точнее оператор)?..

> или ещё лучше так:

>
> for(xmlNodePtr c = parent->children; c; c = c->nextSibling)
> {
> if (IsThisGood(c))
> {
> ...
> }
> }
Чем это хуже?
for(...)
{
    if(!IsThisGood(c)) continue;
    ...
}

Мне, честно говоря, так больше нравится — меньше вложенность {}.

Ладно, в общем, continue — да, легко обходится (даже можно запретить требованиями corporation code style). А что делать
с break? Насколько это мне представляется, это можно обойти только введением специального флага, что засоряет синтаксис.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Приходилось ли вам использовать goto?
От: Pavel Dvorkin Россия  
Дата: 04.04.06 02:53
Оценка: :))) :)
Здравствуйте, zzzale, Вы писали:

Z>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).


Во времена Windows 3.x исходник DefWindowProc был опубликован. И там было такое

goto ICantBelieveThatIUserAGotoStatement;
With best regards
Pavel Dvorkin
Re[9]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:06
Оценка: +4
Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Ну, во-первых, я в таких местах всегда пишу комментарий типа "exit the loop", а во-вторых — как я писал это чисто иррациональное, а не мотивированное большей читабельностью кода. Ну вот заскок у меня такой. Просто иногда бывает "не в тему" заводить очередную булеву переменную, значение которой проверяется наряду с "основным" условием цикла.


SDB>P.S.

SDB>Посто мой был собственно в поддержку "некоторых", на которых ссылался Cyberax.

В Вашем примере:

for (int i = 0; i < 10; ++i)
{
...
    if (some_rare_contition)
    {
        i = 10;        // неявный break :)
    }
    else {
        ...
    }
}


в случае если потребуется изменить количество итераций цикла — надо будет менять две строчки кода. Есть некоторая вероятность, что вы забудете это сделать. А когда начнёте искать ошибку, то этот комментарий "exit the loop" будет сбивать с толку, т.к. сообщает, что здесь выход из цикла.
Re[10]: Приходилось ли вам использовать goto?
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 04.04.06 09:11
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>в случае если потребуется изменить количество итераций цикла — надо будет менять две строчки кода. Есть некоторая вероятность, что вы забудете это сделать. А когда начнёте искать ошибку, то этот комментарий "exit the loop" будет сбивать с толку, т.к. сообщает, что здесь выход из цикла.


Еще раз подчеркну, что не считаю этот код "идеальным" и "образцовым".
[ posted via RSDN@Home 1.1.4 stable SR1 r568, accompanied by silence ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re[2]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:14
Оценка:
Здравствуйте, yurafitt, Вы писали:

Y>Мне нет, а вот в примерах поставляемых с SDK DirectX 7.0 во многих местатх встречал использование goto


А были ли они там оправданы с Вашей точки зрения?
Или это были примеры неграмотного использования языка.
Re[2]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:16
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А болкк интеллектуальных вопросов не нашлось?


VD>Или новое поколени РСДН-еров не умеет пользоваться поиском?


Вопрос не интеллектуальный, а философский.
Однозначного ответа на него найти не получается.
Re[2]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 09:20
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Во времена Windows 3.x исходник DefWindowProc был опубликован. И там было такое


PD>goto ICantBelieveThatIUserAGotoStatement;


Мне когда-то преподаватель показывал примеры на WinAPI, когда следовало применять goto.
Что-то вроде:

void fun()
{
    //... действия
    if(ошибка)goto end_fun;


    //... снова действия
         //вложенный if
         if(что-то)goto end_fin;
   
    //и опять в том же духе.

 normal:
   //что-то сделать
 end_fun:
   //что-то сделать
}
Re[3]: Приходилось ли вам использовать goto?
От: Kluev  
Дата: 04.04.06 09:31
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Мне когда-то преподаватель показывал примеры на WinAPI, когда следовало применять goto.

Z>Что-то вроде:

Z>
Z>void fun()
Z>{
Z>    //... действия
Z>    if(ошибка)goto end_fun;


Z>    //... снова действия
Z>         //вложенный if
Z>         if(что-то)goto end_fin;
   
Z>    //и опять в том же духе.

Z> normal:
Z>   //что-то сделать
Z> end_fun:
Z>   //что-то сделать
Z>}
Z>


Не всегда стоит слушать преподавателей.

void
    func()
{
    do
    {
        if ( error1 )
            break;

        if ( error2 )
            break;

        // well, no errors, do other stuff and exit
        return;
    }
    while (0);
    // вышли брейком
    // обрабатываем ошибку здесь
}
Re[10]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 04.04.06 10:57
Оценка:
Здравствуйте, kan_izh, Вы писали:

_>Ладно, в общем, continue — да, легко обходится (даже можно запретить требованиями corporation code style).

_>А что делать с break?

Ничего не делать, break ни в чём не виноват. Его только нельзя использовать внутри WHILE-DO-END и REPEAT-UNTIL циклов по определению этих циклов. Внутри безусловного цикла LOOP-END инструкция break (т.е. EXIT) — единственный способ завершения цикла.

P. S.
В Си-образных языках безусловный цикл LOOP-END синтаксически обычно записывается как: while (true) {...}.
Re[4]: Приходилось ли вам использовать goto?
От: zzzale  
Дата: 04.04.06 11:21
Оценка:
Здравствуйте, Kluev, Вы писали:

K>Не всегда стоит слушать преподавателей.


K>
K>void
K>    func()
K>{
K>    do
K>    {
K>        if ( error1 )
K>            break;

K>        if ( error2 )
K>            break;

K>        // well, no errors, do other stuff and exit
K>        return;
K>    }
K>    while (0);
K>    // вышли брейком
K>    // обрабатываем ошибку здесь
K>}
K>


Мне тоже пример показался не самым лучшим.
Более точнее:
Z>void fun()
Z>{
Z> //... действия
Z> if(ошибка)goto end_fun;


Z> //... снова действия

Z> //вложенный if
for(...)
Z> {
//...
if(что-то)goto end_fin;
//...
}

Z> //и опять в том же духе.


Z> normal:

Z> //что-то сделать
Z> end_fun:
Z> //что-то сделать
Z>}
Z>
Re[3]: Приходилось ли вам использовать goto?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.06 16:44
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Вопрос не интеллектуальный, а философский.

Z>Однозначного ответа на него найти не получается.

Филосовский он примерно настолько насколько филосовским вопросом является чем закусывать тройной адеколон.

Применение goto можно оправдать только в генерируемом коде. И то толко упрощением генератора.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Приходилось ли вам использовать goto?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.06 16:44
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Мне когда-то преподаватель показывал примеры на WinAPI, когда следовало применять goto.


Он о С говорил или о С++?
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 11.04.06 08:24
Оценка:
Совсем забыл. Зацените else-clause у циклов в питоне. else у цикла не выполяется, если цикл был прерван по break. Сильно подозреваю, что в питоне это сделано специально для решения типичной проблемы временной переменной-флага. Вот пример: если данные уже есть в массиве, то добавлять не надо, в противном случае — их надо добавить:
// всем знакомый паттерн
bool f = false;
for (unsigned i = 0; i < array.size(); ++i)
{
  if (array[i] == data)
  {
    f = true;
    break;
  }
}
if (!f) array.push_back(data);

for (unsigned i = 0; i < array.size(); ++i)
{
  if (array[i] == data)
    break;
}
else array.push_back(data);
Re[9]: Приходилось ли вам использовать goto?
От: WolfHound  
Дата: 11.04.06 17:10
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Совсем забыл. Зацените else-clause у циклов в питоне. else у цикла не выполяется, если цикл был прерван по break. Сильно подозреваю, что в питоне это сделано специально для решения типичной проблемы временной переменной-флага. Вот пример: если данные уже есть в массиве, то добавлять не надо, в противном случае — их надо добавить:

Плохое решение. В таких случаях нужна декомпозиция.
bool Contains(Array const& array, Data const& data)
{
    for (unsigned i = 0; i < array.size(); ++i)
        if (array[i] == data)
            return true;
    retrun false;
}

if (!Contains(array, data))
    array.push_back(data);
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: Приходилось ли вам использовать goto?
От: Olivan Россия  
Дата: 11.04.06 19:00
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Плохое решение. В таких случаях нужна декомпозиция.


или использование готовых алгоритмов
if (std::find(array.begin(), array.end(), data) == array.end())
    array.push_back(data);



Кстати, пример для упражнения
Кё>        CString expr = m_settings.expr;
Кё>        while (1)
Кё>        {
Кё>            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
Кё>            for (size_t i = 0; i < m_settings.rules.size(); ++i)
Кё>            {
Кё>                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
Кё>                {
Кё>                    MessageBox("Syntax error", 0, 0);
Кё>                    goto the_goto;
Кё>                }
Кё>            }
Кё>            break;
Кё>the_goto:;
Кё>        }
Кё>        m_settings.expr = expr;
Кё>

я бы всё-таки переписал с использованием флага:
        CString expr = m_settings.expr;
        bool rules_correct = false;
        while (!rules_correct)
        {
            if (IDOK != DataEditorDialog(expr).DoModal()) return 0;
            
            for (size_t i = 0, rules_correct = true; i < m_settings.rules.size() && rules_correct; ++i)
            {
                if (m_settings.rules[i].active && !m_settings.rules[i].Check(expr))
                {
                    rules_correct = false;
                    MessageBox("Syntax error", 0, 0);
                }
            }
        }
        m_settings.expr = expr;

кода столько же, но имхо так читабельней.
Re[11]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.04.06 09:21
Оценка:
Здравствуйте, Olivan, Вы писали:

O>Кстати, пример для упражнения

...
O>я бы всё-таки переписал с использованием флага:
...
O>кода столько же, но имхо так читабельней.

Пора бы и прекратить предлагать иные варианты решения. Ведь, вообще-то, это
Автор: Сергей Губанов
Дата: 31.03.06
классическая задача линейного поиска имеющая каноническое решение:

i := 0;
WHILE (i < N) & условие(i) DO INC(i) END;
IF i < N THEN условие под номером i не выполнено END
Re[12]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 12.04.06 10:31
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Пора бы и прекратить предлагать иные варианты решения. Ведь, вообще-то, это
Автор: Сергей Губанов
Дата: 31.03.06
классическая задача линейного поиска имеющая каноническое решение:


СГ>i := 0;

СГ>WHILE (i < N) & условие(i) DO INC(i) END;
СГ>IF i < N THEN условие под номером i не выполнено END

А если проверка условия состоит из 10 инструкций и не может быть записана выражением? А зависимость этих 10 инструкций от локальных переменных затруднит выделение его в локальную функцию? Для Оберона это особенно актуально.
Re[13]: Приходилось ли вам использовать goto?
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.04.06 10:55
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>А если проверка условия состоит из 10 инструкций и не может быть записана выражением? А зависимость этих 10 инструкций от локальных переменных затруднит выделение его в локальную функцию? Для Оберона это особенно актуально.


Чего-чего? Вложенная процедура видит все локальные переменные объемлющей процедуры.

PROCEDURE Процедура;

  VAR a, b, c: BOOLEAN;
  i: INTEGER;
  ...

  PROCEDURE условие1 (i: INTEGER): BOOLEAN;
    VAR ....
  BEGIN
    ...
    RETURN ...
  END условие1;

  PROCEDURE условие2 (i: INTEGER): BOOLEAN;
    VAR ....
  BEGIN
    ...
    RETURN ...
  END условие2;

  ...

  PROCEDURE условие (i: INTEGER): BOOLEAN;
  BEGIN
    RETURN условие1(i) & условие2(i) & ...
  END условие;

BEGIN
  ...
  WHILE (i < N) & условие(i) DO INC(i) END;
  ...
END Процедура;

т.е., теоретически, даже можно i не объявлять как параметр процедуры-функции условие(), ведь из неё i и так видно.
Re[14]: Приходилось ли вам использовать goto?
От: Кодёнок  
Дата: 12.04.06 12:14
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Чего-чего? Вложенная процедура видит все локальные переменные объемлющей процедуры.


СГ>PROCEDURE Процедура;

СГ> i: INTEGER;
СГ> PROCEDURE условие1 (i: INTEGER): BOOLEAN;
СГ>т.е., теоретически, даже можно i не объявлять как параметр процедуры-функции условие(), ведь из неё i и так видно.

Действительно, это я напутал.
Re[13]: Приходилось ли вам использовать goto?
От: Kluev  
Дата: 12.04.06 12:21
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Здравствуйте, Сергей Губанов, Вы писали:


СГ>>Пора бы и прекратить предлагать иные варианты решения. Ведь, вообще-то, это
Автор: Сергей Губанов
Дата: 31.03.06
классическая задача линейного поиска имеющая каноническое решение:


СГ>>i := 0;

СГ>>WHILE (i < N) & условие(i) DO INC(i) END;
СГ>>IF i < N THEN условие под номером i не выполнено END

Кё>А если проверка условия состоит из 10 инструкций и не может быть записана выражением? А зависимость этих 10 инструкций от локальных переменных затруднит выделение его в локальную функцию?


Тогда нажимаем кнопку "я сам себе и небо и луна" и пишем уместный код.

А вообще, я например не чувствую, что пишу хуже Вирта или Страуструпа. Поэтому весь мой код — канонический, нет даже байта не-канонического кода.
Re: Приходилось ли вам использовать goto?
От: dead_ricky  
Дата: 14.04.06 00:56
Оценка:
Здравствуйте, zzzale, Вы писали:

Z>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).

Z>Интересуют прежде всего языки С++,С#.

Ну да... Бывает не всегда можешь нормально обяснить человеку, что... Ну в общем использовал
... << RSDN@Home 1.2.0 alpha rev. 645 на SQL Server'e :P>>
Re[5]: Приходилось ли вам использовать goto?
От: Ka3a4oK  
Дата: 21.05.06 09:13
Оценка:
Здравствуйте, Cider, Вы писали:

C>Здравствуйте, Нахлобуч, Вы писали:


Н>>Здравствуйте, Сергей Губанов, Вы писали:


СГ>>>А Вы, пожалуйста, приведите какой-нибудь (канонический) пример в котором устранение goto с неизбежностью повлечёт введение лишнего булевского флага(ов).


Н>>Выйти из двух циклов разом?


C>Неизбежности нет. Например, оператор break (не помню, есть ли в плюсах break на метку).

Нет.

C>Можно бросить исключение.

За это — .
... << RSDN@Home 1.1.4 stable rev. 510>>
Re: Приходилось ли вам использовать goto?
От: Nazik Россия  
Дата: 21.05.06 09:31
Оценка:
В годы учебы в Лицее однажды мне показалось, что без данного оператора не обойтись (для решения какой-то учебной задачки). Однако, его использование привело к очень скорому появлению "2" в журнале, поэтому с тех пор более его не использую

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

Z>Я имею в виду случаи когда ДЕЙСТВИТЕЛЬНО была необходимость применять этот оператор (желательно с примером и описанием ПО).

Z>Интересуют прежде всего языки С++,С#.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.