LINUX.ORG.RU

Нужен ли goto


0

1

Что бы не повторяться ...

Аналог switch, но более эффективный http://www.sql.ru/forum/1156759-a/analog-switch-no-bolee-effektivnyy?hl=

На C++ без него реализация конечного автомата выглядит как способ вычисления выражения 2 + 2 с использованием тройного интеграла ... /использование классов, .../

Понятно, что структурированная программа - хорошо. Но не хорошо у программистов забирать goto.

here we go again

anonymous
()

Аналог switch, но более эффективный

Посмотрел вашу ссылку - на форуме sql.ru вас забанили. Там добрая администрация, мало кому удаётся добиться забанивания.

Partisan ★★★★★
()

goto нужен крайне редко. И лучше им не пренебрегать, используя только для положенных целей: выход из глубины вложенных циклов и переход к обработчику ошибок в конце функции (а перед меткой обработчика располагаем return status; хотя, конечно, в данном случае можно вместо goto обойтись вложенной функцией).

anonymous
()
Ответ на: комментарий от anonymous

Искусством написания плохих программ владеют многие /это не к вам лично относится/

vladimirmir2016
() автор топика
Ответ на: комментарий от anonymous

Таки прошел по ссылке. Ну и бред:

для доступа к 29 по счету case, компилятор должен произвести 29 операций сравнения

Товарищ абсолютно не знаком с матчастью, и не понимает, чем switch от if/else if/else отличается! Ну посмотри хотя бы дизассемблер!!! Нормальный gcc превращает switch(X) в goto [base_address + delta*table(X)].

anonymous
()
Ответ на: комментарий от vladimirmir2016

Очень даже в теме. И много ассемблерных листингов просмотрел, которые генерит gcc. Так что, не надо тут!!!

anonymous
()
Ответ на: комментарий от anonymous

Верю что у вас имеется опыт работы с asm /да и у меня поверьте также/. Но речь же не об этом ...

В топике http://www.sql.ru/forum/1156759-a/analog-switch-no-bolee-effektivnyy?hl= приведены примеры того как использование goto Express позволяет много упростить код. Использование массива /для конечного/ в котором можно указать адреса переходов много упрощает реализацию например конечного автомата.

vladimirmir2016
() автор топика
Ответ на: комментарий от vladimirmir2016

Чувак, а ничего, что gcc «под капотом» сгенерит значительно более оптимизированный код, нежели ты будешь по таблице с goto вручную лепить?

anonymous
()
Ответ на: комментарий от vladimirmir2016

Ну и нефиг мастдайным говном пользоваться!

И вообще, здесь как-бы ЛОР, а не форум рабов на галерах или гомосеков каких-нибудь!

anonymous
()
Ответ на: комментарий от xmikex

Удваиваю

void h(void);
asm(R"(.globl _h;_h:
  call ...
  movb $1,...
  jmp  ...)");

const auto a=...;
unsigned long _;
VirtualProtect((void*)a,5,PAGE_EXECUTE_READWRITE,&_);
*(uint8_t*)a=0xe9;
*(uint32_t*)(a+1)=(uint32_t)h-a-5;

anonymous
()
Ответ на: комментарий от anonymous

Хороший пример, но мне так более предпочтителен оператор goto ExpressLabel

vladimirmir2016
() автор топика

Если ты не пишешь что-то, где важно экономить каждый такт, то понятный структурнный код гораздо важнее сомнительных оптимизаций.

WitcherGeralt ★★
()
Ответ на: комментарий от WitcherGeralt

Во-во! Вне микроконтроллеров goto крайне редко бывает нужен. Зачастую логику можно более прозрачно реализовать. Потому как goto усложняет чтение и в функциях, занимающих больше пары экранов, лучше goto вообще не использовать (разве что метка в пределах одного экрана находится).

anonymous
()
Ответ на: комментарий от WitcherGeralt

100% согласен. Конечно goto должен быть использован только там где он уместен, но делать из него «козла отпущения» также не правильно.

Sorry за повтор. Вспомним танцоров, ...

vladimirmir2016
() автор топика
Ответ на: комментарий от vladimirmir2016

Тоже верно. погромистов, которые говорят «goto ни в коем случае нельзя использовать», надо за яйца в

anonymous
()
Ответ на: комментарий от anonymous

В этом вопросе /как любит выражаться Горбачев/ у меня с вами конcенсус. Но строже нужно быть, строже ...

vladimirmir2016
() автор топика

Аналог switch, но более эффективный http://www.sql.ru/forum/1156759-a/analog-switch-no-bolee-effektivnyy?hl=

У меня для тебя плохие новости, вот cpp:

movl    4(%rsp), %eax
        addl    $-1, %eax
        cmpl    $13, %eax
        ja      .LBB0_16
        jmpq    *.LJTI0_0(,%rax,8)
.LBB0_2:
        movl    $2, 4(%rsp)
        jmp     .LBB0_16
.LBB0_3:
        movl    $4, 4(%rsp)
        jmp     .LBB0_16
.LBB0_4:
        movl    $6, 4(%rsp)
        jmp     .LBB0_16
.LBB0_5:
        movl    $8, 4(%rsp)
        jmp     .LBB0_16
.LBB0_6:
        movl    $10, 4(%rsp)
        jmp     .LBB0_16
.LBB0_7:
        movl    $12, 4(%rsp)
        jmp     .LBB0_16
.LBB0_8:
        movl    $14, 4(%rsp)
        jmp     .LBB0_16
.LBB0_9:
        movl    $16, 4(%rsp)
        jmp     .LBB0_16
.LBB0_10:
        movl    $18, 4(%rsp)
        jmp     .LBB0_16
.LBB0_11:
        movl    $20, 4(%rsp)
        jmp     .LBB0_16
.LBB0_12:
        movl    $22, 4(%rsp)
        jmp     .LBB0_16
.LBB0_13:
        movl    $24, 4(%rsp)
        jmp     .LBB0_16
.LBB0_14:
        movl    $26, 4(%rsp)
        jmp     .LBB0_16
.LBB0_15:
        movl    $28, 4(%rsp)
.LBB0_16:
        xorl    %eax, %eax
        popq    %rcx
        retq
https://godbolt.org/z/XYPx9y

xpahos ★★★★★
()
Ответ на: комментарий от anonymous

в функциях, занимающих больше пары экранов,

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

По сабжу, есть два типа людей: тот, у кого goto не вызывает фгм-эмоций, и тот, кто обосрется при одном его упоминании, несмотря на то, что никогда не сталкивался с его проблемным использованием вживую. Если брать шире, то пора бы уже заточенным редакторам и IDE закреплять стек func/for/if/{}/etc вверху экрана и делать прочие визуальные пометки, чтобы всегда было ясно, как вложено текущее окно кода и куда прыгнет goto или любой другой оператор перехода/вызова.

Когда собираются юзеры, они обсуждают UX, верстку и инфографику. Когда собираются программисты, они срутся о goto.

anonymous
()

Где это, интересно, у вас switch тормозит? Я видел примеры, где примеры, где switch используется в качестве исполнителя ассемблерных инструкций виртуальной машины, и ничего, главное enum последовательно делать, иначе хэшфункция будет сложная.

EvilSpirit
()
Ответ на: комментарий от vladimirmir2016

goto ExpressLabel по существу обеспечивал бы дополнительную функциональность при разработке.

Ни чего не имею против switch, но у него имеются некоторые ограничения в его использовании.

По существу switch улучшает читабельность кода по сравнению с if условие1 then команды1 elsif условие2 then команды2 elsif условие3 then команды3 ... else команды end;

goto ExpressLabel /повторюсь/ обеспечивал новую разновидность ветвления.

К примеру при реализации конечного автомата удобно иметь матрицу переходов. Так вот она как раз и содержала бы ExpressLabel, а goto ExpressLabel без всяких switch и if позволял произвести переход к требуемому участку программы.

Не реализуют его из-за разных причин: - не популярность goto;

- сложность реализации /вот так просто из метода класса прыгнуть куда то можно, но при этом компилятор должен многое учесть/. ИМХНО в этом случае проще всего такой goto диагностировать как ошибочный.

vladimirmir2016
() автор топика

В switch не обязательно 29 операций сравнения. Нормальный компилятор построит хеш-функцию и всё будет происходить за одно какое-нибудь взятие по модулю и один переход по вычисленной метке.

Но насчёт goto согласен - оно иногда нужно.

den73 ★★★★★
()
Ответ на: комментарий от den73

Если имеются такие хеш-функцию /которые не приведут к коллизии/, то замечательно.

Не подскажете ли где можно посмотреть реализацию алгоритма построения такой хеш-функции?

vladimirmir2016
() автор топика
Ответ на: комментарий от vladimirmir2016

Таки почему вы отвечаете вопросом на вопрос?

anonymous
()

Да кто goto будет забирать у прогеров? ) Ну в ++ действительно если писать в современном стиле гото скорее всего не пригодится, а вот в Си его активно юзают, например запустите grep -iRI «goto» . в каталоге с кодом ядра - там много тысяч строк гото нагрепается.

Особо не смотрел где он там грепается, но когда-то кодил на Си, и там местами goto был действительно не заменим в вопросах читаемости и краткости кода.

Например представим что идет разнообразная работа с объектами на куче (которые создались в ф-ии), и если какая-то ошибка которая не позволяет дальше работать - то очень удобно сделать

goto error_state;
а за этой меткой сделать код очистки всего что было выделено.

О, вот оно, даже гуглится легко пример полезности готов в Си https://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c

bonta ★★★★★
()
Последнее исправление: bonta (всего исправлений: 1)

Нужен ли goto

Конечно же нет. Понаставят своих гото, а потом компилятор ругается на пропуск инициализации переменной. Приходится объявлять все переменные до переходов. А это уже окаменелый сишный стиль.

ox55ff ★★★★★
()
Ответ на: комментарий от bonta

Такой стиль используется в многих проектах.

Далее суждение не к вам лично относящееся.

Вообще то топик не о том, что goto должен быть в каждой четной строке кода ...

ИМХНО /sorry повторюсь/ goto ExpressLabel обеспечивал бы новую разновидность ветвления и при правильном понимании для чего он и какая от него польза мог бы помочь реализовать алгоритмы более просто без ущерба к их читабельности ...

vladimirmir2016
() автор топика
Ответ на: комментарий от bonta

Ну в ++ действительно если писать в современном стиле гото скорее всего не пригодится

Пригодится. Тот же ragel генерирует фсм с goto. Возможно можно написать условия без goto, но я бы не стал этого делать.

xpahos ★★★★★
()
Ответ на: комментарий от vladimirmir2016

Не знаю, но, наверное, в исходниках компиляторов можно. На самом-то деле даже при наличии коллизии количество сравнений может уменьшиться. Простейшая хеш-функция - это отбрасывание верхних разрядов неотрицательного числа - получается взятие по модулю 2^n. С помощью прибавления к исходному числу константы можно подогнать под нужный диапазон. А дальше совпавшие метки складываем в «ведро» и там уже действуем перебором.

И ещё вот это: http://www.cyberforum.ru/blogs/18334/blog91.html

Обратите внимание, что switch - это не структурное программирование вообще, т.к. метка может быть внутри if или цикла, вложенного в switch.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от vladimirmir2016

Конечно же, Си - это не «тонкий слой абстракции над ассемблером», а существенное ограничение общности ассемблера и потеря контроля над происходящим. Мне кажется, под тонкий слой абстракции скорее подходит какой-нибудь c--.

den73 ★★★★★
()
Ответ на: комментарий от den73

В какой-то мере нынешний C /да и C++ без классов/ меня устраивает.

Почему?

Ну что такое классы в C++ - один из подходов к работе с объектами.
К счастью C/C++ позволяют разработчику создать любую иную
систему для работы с объектами.

Скажу по секрету /вольной трактовкой строк из одной ранее
популярной песни/ - «Мы на классы больше не глядим ...».

vladimirmir2016
() автор топика

Нужен ли goto
20.10.2018 16:02:09

ты лет так на 30 опоздал. Всё уже обсосали по тыщу раз.

Deleted
()
Ответ на: комментарий от den73

Хорошая ссылка.
Спасибо.
Ответить вам не могу /так как флуда после ответа будет страниц 5/.
Но намеком скажу.
То о чем говорится в статье не во всех компиляторах реализовано.

vladimirmir2016
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.