О безусловных переходах
От: Khimik  
Дата: 22.04.15 19:36
Оценка:
Извиняюсь если мой вопрос совсем ламерский, или если баян. Где-то я читал, что операторы безусловного перехода goto хорошему программисту не нужны, их надо заменять на стандартные блоки. Последние 9 лет я действительно обходился без goto, но недавно возникла задача, в которой обойтись без этого оператора было бы весьма неудобно (нужно перейти в более раннюю часть кода изнутри блока begin..end. Чтобы обойтись без goto, можно было бы поставить блок while…end; (и где-то внутри него continue, но с goto получилось явно изящнее. После этого у меня создалось ощущение, что в сложных алгоритмах оператор goto всё-таки приходится иногда применять, без этого не обойтись. Я прав?
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re: О безусловных переходах
От: AlexRK  
Дата: 22.04.15 19:39
Оценка:
Здравствуйте, Khimik, Вы писали:

K>Извиняюсь если мой вопрос совсем ламерский, или если баян. Где-то я читал, что операторы безусловного перехода goto хорошему программисту не нужны, их надо заменять на стандартные блоки. Последние 9 лет я действительно обходился без goto, но недавно возникла задача, в которой обойтись без этого оператора было бы весьма неудобно (нужно перейти в более раннюю часть кода изнутри блока begin..end. Чтобы обойтись без goto, можно было бы поставить блок while…end; (и где-то внутри него continue, но с goto получилось явно изящнее. После этого у меня создалось ощущение, что в сложных алгоритмах оператор goto всё-таки приходится иногда применять, без этого не обойтись. Я прав?


Обойтись без goto можно всегда. Есть люди, которые считают, что иногда goto делает код проще/лучше. Лично я считаю, что это не так. По моему мнению, если goto делает код проще, то это плохой код.
Re[2]: О безусловных переходах
От: WolfHound  
Дата: 22.04.15 20:11
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Обойтись без goto можно всегда. Есть люди, которые считают, что иногда goto делает код проще/лучше. Лично я считаю, что это не так. По моему мнению, если goto делает код проще, то это плохой код.

Удачи переписать без goto. Производительность пострадать не должна.
  public struct ExtensionRuleParserState
  {
    public mutable newResult : int;
    public mutable newEndPos : int;
    public mutable bestResult : int;
    public mutable bestEndPos : int;
    public mutable lastResult : int;
    public mutable curTextPos : int;
    public mutable parseResult : ParseResult;

    public Append() : void
    {
      assert3(newResult > 0);

      //очищаем флаги
      parseResult.rawTree[newResult] = parseResult.rawTree[newResult] & ExtensibleRuleParser.RawTreeMask.Id;

      //добавляем в список
      parseResult.rawTree[newResult + ExtensibleRuleParser.RawTreeOfs.Next] = lastResult;
      lastResult = newResult;

      // выбираем лучшее правило: побеждает то правило, у которого находится поле спарсившее больше текста
      // если оба правила имеют одинаковое кол-во полей, размеры которых идентичны, ситуация считается неоднозначностью
      when (bestResult <= 0) goto new_better;
      if   (bestEndPos < 0)  if   (newEndPos >= 0) goto new_better; else goto equal;
      else                   when (newEndPos < 0)  goto best_better;

      def newTokens  = parseResult.TokenEnumerator1.Start(newResult,  curTextPos);
      def bestTokens = parseResult.TokenEnumerator2.Start(bestResult, curTextPos);

      while (true)
      {
        def newSize = newTokens.NextTokenSize();
        def bestSize = bestTokens.NextTokenSize();
        when (newSize > bestSize) goto new_better;
        when (newSize < bestSize) goto best_better;
        when (newSize < 0)        goto equal;
      }

    label equal;//АСТ равен лучшему. Неоднозначность.
      parseResult.rawTree[newResult] = parseResult.rawTree[newResult] | ExtensibleRuleParser.RawTreeFlags.Equal;
      assert(bestEndPos == newEndPos);
      return;

    label new_better;//Новый АСТ лучше
      bestEndPos = newEndPos;
      bestResult = newResult;
      parseResult.rawTree[newResult] = parseResult.rawTree[newResult] | ExtensibleRuleParser.RawTreeFlags.Best;
      return;

    label best_better;
      return;
    }
  }
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: О безусловных переходах
От: LaptevVV Россия  
Дата: 22.04.15 20:18
Оценка: 6 (1) +4
Здравствуйте, WolfHound, Вы писали:

WH>Удачи переписать без goto. Производительность пострадать не должна.

А что, изначально вместо goto вызов функции поставить — некошерно будет?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: О безусловных переходах
От: AlexRK  
Дата: 22.04.15 20:29
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

ARK>>Обойтись без goto можно всегда. Есть люди, которые считают, что иногда goto делает код проще/лучше. Лично я считаю, что это не так. По моему мнению, если goto делает код проще, то это плохой код.

WH>Удачи переписать без goto. Производительность пострадать не должна.

Пардон, но рефакторить весьма мусорный код в мои планы не входит.

Лаптев, кстати, правильно написал — выносите в функцию все, что в goto.
Re: О безусловных переходах
От: vmpire Россия  
Дата: 22.04.15 20:36
Оценка: +6
Здравствуйте, Khimik, Вы писали:

K>Извиняюсь если мой вопрос совсем ламерский, или если баян. Где-то я читал, что операторы безусловного перехода goto хорошему программисту не нужны, их надо заменять на стандартные блоки. Последние 9 лет я действительно обходился без goto, но недавно возникла задача, в которой обойтись без этого оператора было бы весьма неудобно (нужно перейти в более раннюю часть кода изнутри блока begin..end. Чтобы обойтись без goto, можно было бы поставить блок while…end; (и где-то внутри него continue, но с goto получилось явно изящнее. После этого у меня создалось ощущение, что в сложных алгоритмах оператор goto всё-таки приходится иногда применять, без этого не обойтись. Я прав?

Нужно писать просто и понятно. Если чтобы избавится от goto можно только ценой сильного усложенния — я бы оставил goto.
Другое дело, что за последние 10 лет мне это понадобилось ровно 2 (два) раза, то есть эти случаи не частые.
Ну, это если не брать языки где без goto в принципе не обойтись.
Учтите, что continue, return и break (в С-подобных языках) это те же самые goto, точнее — ограниченные частные версии goto для наиболее употребительных случаев. И соответственно, запутать код они могут не хуже.
Re: О безусловных переходах
От: Evgeny.Panasyuk Россия  
Дата: 22.04.15 20:36
Оценка: 15 (2) +6
Александр Степанов, автор STL:

http://tinyurl.com/lzdxs3r
Я очень горд, что в этой книжке (Elements of Programming) есть, вы сейчас просто @#$%&%@#, GOTOS. Почему? Потому что в какой-то момент мы показываем, специально, потому что знаем, что вы будете кричать БУУУУУ и писать письма, может быть не все, но некоторые — мне всегда пишут письма что я дурак — потому что я не верю в объектную ориентацию, я использую goto — пропащий человек. И многие люди, в программировании есть такая идея что люди считают что это очень мило написать незнакомому человеку письмо говорящие что "ты дурак". Даже если вы так думаете — вы мне не говорите, потому что — не нужно, не обязательно.
Мы используем goto, для чего — потому что у нас есть структура которая реально является конечным автоматом. Если вы описываете конечный автомат, что он делает — он переходит из состояния этого в состояние то. Как нужно переходить из одного состояния в другое? Есть правильная инструкция — называется goto: идите от туда — туда. И структура программы становится очень элегантной.
То есть идея Дейкстры, Дейкстра великий человек — вы не думайте что $#%@#$%@#$, но он конечно же был не прав, потому что он думал, что плохая программа, потому что она пользуется какой-то синтаксической структурой. Нет — программа плохая, если она плохая.
То есть может быть очень красивая программа на языке Assembler — очень элегантная. Может быть очень плохая программа на Java, уверяю вас.
Немецкий язык такой непоэтичный — но какая поэзия Самые красивые песни на каком языке? На немецком — Шуберт — необыкновенная красота. Хотя у них там гортанный, странный язык, но невероятно красивый.
Всё можно сделать. goto может быть красивым. Я не верю в синтаксические лишения в семантических вопросах.
В меня всю жизнь камнями кидают, потому что я всё время такие вещи говорю — и мне говорят что я дурак. Но я не пытаюсь просто сказать дерзость. Я на самом деле пытаюсь объяснить какие-то вещи и в этой книжке никаких дерзостей.

Re[3]: О безусловных переходах
От: vmpire Россия  
Дата: 22.04.15 20:43
Оценка:
Здравствуйте, WolfHound, Вы писали:

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


ARK>>Обойтись без goto можно всегда. Есть люди, которые считают, что иногда goto делает код проще/лучше. Лично я считаю, что это не так. По моему мнению, если goto делает код проще, то это плохой код.

WH>Удачи переписать без goto. Производительность пострадать не должна.
Здесь как раз goto не нужен.
Как вариант, можно переписать в единую цепочку if/else if/else (сейчас последный else неявный) и вынести все три кейса в отдельные методы.
Re[4]: О безусловных переходах
От: WolfHound  
Дата: 22.04.15 20:49
Оценка: -3 :)
Здравствуйте, AlexRK, Вы писали:

ARK>Пардон, но рефакторить весьма мусорный код в мои планы не входит.

Так быстро слил...

ARK>Лаптев, кстати, правильно написал — выносите в функцию все, что в goto.

Это сделает код лучше? Нет.
Медленнее? Да.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: О безусловных переходах
От: WolfHound  
Дата: 22.04.15 20:49
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Здесь как раз goto не нужен.

V>Как вариант, можно переписать в единую цепочку if/else if/else (сейчас последный else неявный) и вынести все три кейса в отдельные методы.
Покажи класс.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: О безусловных переходах
От: vmpire Россия  
Дата: 22.04.15 20:59
Оценка:
Здравствуйте, WolfHound, Вы писали:

V>>Здесь как раз goto не нужен.

V>>Как вариант, можно переписать в единую цепочку if/else if/else (сейчас последный else неявный) и вынести все три кейса в отдельные методы.
WH>Покажи класс.
Вы не понимаете предложенного решения, или просто хотите, чтобы за вас сделали работу?
Работу делать не буду, но что непонятно — объясню.
Re[6]: О безусловных переходах
От: WolfHound  
Дата: 22.04.15 21:18
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Вы не понимаете предложенного решения, или просто хотите, чтобы за вас сделали работу?

V>Работу делать не буду, но что непонятно — объясню.
Я понимаю, что ты предлагаешь написать кучу кода, на ровном месте сделав решение хуже.
Осталось, чтобы и ты это понял.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: О безусловных переходах
От: AlexRK  
Дата: 22.04.15 21:19
Оценка: 1 (1) +5
Здравствуйте, WolfHound, Вы писали:

ARK>>Пардон, но рефакторить весьма мусорный код в мои планы не входит.

WH>Так быстро слил...

Сочувствую, в следующий раз сливайте помедленнее.

Если по теме: приводите не портянку говнокода с кучей не относящихся к делу деталей, а краткий псевдокод, акцентирующий внимание на проблеме и/или решении.
А пока что — номер не прошел.

ARK>>Лаптев, кстати, правильно написал — выносите в функцию все, что в goto.

WH>Это сделает код лучше? Нет.

Да, это сделает код лучше.

WH>Медленнее? Да.


Только если компилятор глупый.
А так инлайн функций давно уже применяется.
Re[3]: О безусловных переходах
От: Кодт Россия  
Дата: 22.04.15 21:38
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Удачи переписать без goto. Производительность пострадать не должна.


На оптимизирующий компилятор закладываться можно? Или предполагается, что это всего лишь ассемблер с красивым синтаксисом?

Самое простое с т.з. рефакторинга в данном случае — написать три локальные функции, и вместо goto new_better делать return new_better(). Полагая, что компилятор их проинлайнит.
Либо понадеяться, что компилятор способен трассировать булевы флаги. Полное покрытие кода — это дело неподъёмное, но уж два-три флага отследить (00 — ещё неизвестно, 01 — новый лучше, 10 — старый лучше, 11 — они равны; либо 0xx — ещё неизвестно, 10x — они равны, 110 — новый лучше, 111 — старый лучше).
Причём для архитектуры с условными операциями (ARM) это позволит даже без лишних ветвлений обойтись. Код в единственном месте ветвится по необходимости — в цикле; остальное всё исполняется подряд.
Перекуём баги на фичи!
Re[6]: О безусловных переходах
От: WolfHound  
Дата: 22.04.15 21:42
Оценка:
Здравствуйте, AlexRK, Вы писали:

ARK>Если по теме: приводите не портянку говнокода с кучей не относящихся к делу деталей, а краткий псевдокод, акцентирующий внимание на проблеме и/или решении.

Тут всего 40 строк.

WH>>Это сделает код лучше? Нет.

ARK>Да, это сделает код лучше.
Замена goto XXX; на { XXX(); return; } код лучше не сделает.

WH>>Медленнее? Да.

ARK>Только если компилятор глупый.
ARK>А так инлайн функций давно уже применяется.
Инлайн сделает несколько копий кода. Больше кода -> больше промахов кэша.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: О безусловных переходах
От: WolfHound  
Дата: 22.04.15 21:58
Оценка:
Здравствуйте, Кодт, Вы писали:

К>На оптимизирующий компилятор закладываться можно? Или предполагается, что это всего лишь ассемблер с красивым синтаксисом?

Только если компилятор способен переписать код в то, что написал я.
Я знаю технику с помощью, которой компилятор может это сделать. Но не знаю, применяет ли её кто либо.

К>Самое простое с т.з. рефакторинга в данном случае — написать три локальные функции, и вместо goto new_better делать return new_better(). Полагая, что компилятор их проинлайнит.

Но что это даст? Чем оно принципиально отличается от goto кроме того что там нет слова goto?
Но можно пойти ещё дальше. Есть верование, что функция должна иметь ровно один выход. Чтобы соответствовать ему придётся вообще прыгать вокруг флагов.

К>Либо понадеяться, что компилятор способен трассировать булевы флаги.

Тут я вообще не понял, что ты предлагаешь.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: О безусловных переходах
От: Evgeny.Panasyuk Россия  
Дата: 22.04.15 22:59
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

К>>На оптимизирующий компилятор закладываться можно? Или предполагается, что это всего лишь ассемблер с красивым синтаксисом?

WH>Только если компилятор способен переписать код в то, что написал я.
WH>Я знаю технику с помощью, которой компилятор может это сделать. Но не знаю, применяет ли её кто либо.

Что именно? Merge'ить код после инлайнинга с помощью безусловных переходов? Компиляторы C++ это умеют.
Например смотри вот тут
Автор: Evgeny.Panasyuk
Дата: 20.10.14
секцию "ASM для N=4" — там есть jmp на код перед ret, который разделяется несколькими ветками, хотя в самом заинлайненом коде этого не было — каждый вариант был сам по себе.
С другой стороны компилятор может решить этого не делать, даже если умеет.

К>>Самое простое с т.з. рефакторинга в данном случае — написать три локальные функции, и вместо goto new_better делать return new_better(). Полагая, что компилятор их проинлайнит.

WH>Но что это даст? Чем оно принципиально отличается от goto кроме того что там нет слова goto?

Я например предпочитаю делать код функций короче, и выносить из них по возможности даже однократно используемый код.
Если же тебя твоя версия устраивает — не вижу никакого криминала.

WH>Но можно пойти ещё дальше. Есть верование, что функция должна иметь ровно один выход. Чтобы соответствовать ему придётся вообще прыгать вокруг флагов.


Да, это такого же рода предрассудки. Другой пример — гипертрофированная боязнь функций, мол всё должно быть объектом
Автор: 0x7be
Дата: 09.04.15
.
Re[7]: О безусловных переходах
От: vmpire Россия  
Дата: 22.04.15 23:44
Оценка:
Здравствуйте, WolfHound, Вы писали:

V>>Вы не понимаете предложенного решения, или просто хотите, чтобы за вас сделали работу?

V>>Работу делать не буду, но что непонятно — объясню.
WH>Я понимаю, что ты предлагаешь написать кучу кода, на ровном месте сделав решение хуже.
Понимание неправильное по обоим пунктам.
Вам это решение уже разжевали
Автор: Кодт
Дата: 23.04.15


WH>Осталось, чтобы и ты это понял.

Ваша аргументация своей правоты меня восхищает.
Re[8]: О безусловных переходах
От: WolfHound  
Дата: 23.04.15 00:20
Оценка:
Здравствуйте, vmpire, Вы писали:

WH>>Осталось, чтобы и ты это понял.

V>Ваша аргументация своей правоты меня восхищает.
Ну ты код то покажи.
... << RSDN@Home 1.2.0 alpha 5 rev. 62>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[7]: О безусловных переходах
От: AlexRK  
Дата: 23.04.15 06:52
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Инлайн сделает несколько копий кода. Больше кода -> больше промахов кэша.


У вас там кода немного, все копии влезут.

И рассуждение само по себе странное. У вас все программы из одной функции состоят? А то вдруг производительность того, просядет.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.