LINUX.ORG.RU

do{} while(0) вместо вложенных ифов

 ,


2

4

Привет!
Народ, откуда пошла такая конструкция?

do
{
 if ( !cond0 ) break;
 foo();
 if ( !cond1) break;
 bar();
 //...
 if ( !condN) break;
return true;
} while ( 0 )
return false;


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


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

Смотря кем

Всеми, кто в теме.

Я имел ввиду один return на функцию

А откуда такое желание иметь один return на функцию? Где ты этого бреда набрался?

Срачей по поводу возврата в несколько точек пока не слышал(видимо, не сильно популярно)

Неудивительно. Эти срачи по поводу spaghetti code и шуточки про comefrom были пол-века лет назад. Сейчас этот вопрос, как я уже сказал, в основном неактуален, т.к. goto нынче не тот.

no-such-file ★★★★★
()
Ответ на: комментарий от Deleted

Самое смешное, что скорее всего выхлоп в асме при -O2 с goto и то что в оп-посте будет одинаковый. Не проверял, но предполагаю=)

Dudraug ★★★★★
()
Ответ на: комментарий от no-such-file

А откуда такое желание иметь один return на функцию?

Да у меня-то такого желания нет, но в нескольких местах видел

Deleted
()

это доисторическая хуйня с баттла линуса против танненбаума. пиши на баше и не выкабенивайся

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

И ищем скобки сквозь простыню. Как раз на это и матерюсь.

AlexAT
()

Ну и да, гото - офигенный способ сказать компилеру/интерпретеру, что вот сейчас вот эти N скоупов мы дестроим оптом, а вот эти M вообще не создаём.

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

То что goto плохо по факту считают только старые бабки - преподы программирования на первых курсах универа. Они то в бошку и срут будущим разработчикам=)

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

В макросах можно юзать что угодно, программисту-пользователю этих макросов этого не видно. Хоть ассемблерные вставки. Это уже детали реализации, так сказать. А в обычном коде юзать цикл для goto вместо, непосредственно, goto, выглядит странно. Хотя в той же жаве goto просто нет, поэтому, конечно, можно считать такой код неким паттерном. Но мне всё равно не нравится.

Legioner ★★★★★
()

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

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

В свете этой теории досрочный выход из цикла (break) — ровно такое же нарушение

Это кто тебе такую херню рассказал? break заканчивает цикл, точно также как если бы он закончился по условию (собственно это и есть окончание цикла по дополнительному условию). С точки зрения структуры программы тут нет никакой разницы. А что плохо, так это делать goto из цикла к чёрту на рога.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Это кто тебе такую херню рассказал?

Это ещё дядя Боб рассказывал, но ссылку на видосик дать не могу. Вот посмотри хотя бы для начала в википедии (https://ru.wikipedia.org/wiki/Структурное_программирование#Принципы_структурн...). Принципы 2 и 6.

unterwulf
()

1.

посмотри на https://www.tuhs.org/ там всяко в юникс-ископаемых можно найти ранейшее использование сей конструкции.

2.

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

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

дядя Боб

Шёл 21й век, регистранты все еще надрачивали на дилетантов-мошенников...

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

Принципы 2 и 6.

Да откуда вы такие дебилы берётесь? Я уже тут в теме объяснял, что такое «одна точка выхода». Ещё раз специально для тебя, break не нарушает принципы структурного программирования, потому что код с break всегда можно преобразовать в код без break, а только с условным выполнением частей цикла. Т.о. break это просто другая (более краткая) форма записи. А если ты не согласен, то надо не ссылаться на википедию, в которой ты всё равно ничего не понял, а привести пример кода с break, который нельзя преобразовать в полностью эквивалентный структурный код без break.

no-such-file ★★★★★
()

До C++11 были боль и страдания, либо нелепый пустой цикл, либо куча вложенностей с мутабельными переменными, либо вынос кода в отдельную функцию, что раздирает читабельный текст на несколько несвязных кусков.

С появлением лябмд всё упростилось, теперь скоуп функции можно встаивать внутрь кода, как-то так:

const int value = [&] {
    if (cond1) return -5;
    if (cond2) return foo();
    bar();
    if (cond3) return baz();
    return 42;
}();
Dendy ★★★★★
()
Последнее исправление: Dendy (всего исправлений: 1)
Ответ на: Анонимус одобряет от anonymous

The problem appears to come down to the ability of the compiler to correctly optimize the device; it may also interfere with pipelining and branch prediction on some architectures.[6] When numerous instances of Duff's device were removed from the XFree86 Server in version 4.0, there was an improvement in performance and a noticeable reduction in size of the executable.[7]

haha_classic.jpg

ты сам то статью читал? Аптимизаторы -..- ..- . .-- .---

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

RETURN_IF_ERROR(CreateWindowEx(...));

долбоебизм и малолетие.

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

гляди к c+9000 додумаются до option type и патерн матчинга.

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

ты сам то статью читал? Аптимизаторы

Тебя ж просили пройти мимо? Выдумал себе что-то, вырвал предложение из контекста.

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

А если перед return нужно почистить ресурсы, то не проще ли всё-таки сделать goto туда где всё подчистится?

Deleted
()
Ответ на: комментарий от no-such-file

Это кто тебе такую херню рассказал?
Да откуда вы такие дебилы берётесь?
не ссылаться на википедию, в которой ты всё равно ничего не понял

Стыдно истерить при обсуждении технических вопросов.

break не нарушает принципы структурного программирования

Одно дело принципы, другое дело способ их выражения. При помощи аккуратного применения goto тоже можно писать структурный код. Только он будет ужасно читаться и легко ломаться при внесении изменений. Вот ещё почитать: https://en.wikipedia.org/wiki/Structured_programming#Early_exit

привести пример кода с break, который нельзя преобразовать в полностью эквивалентный структурный код без break.

Это не имеет отношения к обсуждаемому вопросу. goto в конец функции ровно также можно выразить в терминах структурного программирования.

Я веду речь о том, что если не упарываться на счёт каноничности, то goto (и ещё некоторые упомянутые в треде техники) являются более лаконичными и выразительными практиками, в отличие от приведённого цикла.

unterwulf
()

посоны, а ретурн посреди цикла не ломает структурность? гоуту - плохо, бряк - плохо, а ретурн ок?

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

Но он же всегда кидает в чётко определённую точку программы.

anonymous
()

А если заменить break на return false?

KivApple ★★★★★
()
Ответ на: комментарий от no-such-file

Это кто тебе такую херню рассказал?

Дейкстра еще, году так в 68-м, начав специальную олимпиаду «X considered harmful» :) А щас «кэшфрендли» товарищи считают, что брякать (и вложенные циклы тоже) — это не кэшфрендли, а нужно знать свои данные (ничо не мешает превратить вложенные циклы в один общий) и циколы до конца проходить :)

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

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

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

Помню писал мой однокурсник программу СМО с goto, после пары сотен строк кода там черт ногу сломит, после тысячи он сам перестал понимать что там происходит, после 1500 он всё с нуля переписал по-человечески.

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

На сишке без goto невозможно писать.

Я на нём лет 10 писал. Использовать GOTO ни разу потребности не возникло :)

Собственно, я за 30 лет программистской практики, переходы использовал только в машинных кодах/ассемблере, на Focal, FORTRAN и на старых Бейсиках. В последние лет 25 не использовал никогда :D

KRoN73 ★★★★★
()

ЕМНИП, Дейкстра говорил о том, что у блока кода должна быть единственная точка выхода. То есть, в «настоящем» процедурном программировании break и continue запрещены, а return должен быть лишь в конце функции. Всё остальное — по сути, прикрытое goto. А стало быть, нет смысла уродовать код, там, где красивее использовать этот оператор. Все равно, того самого «настоящего» процедурного стиля не будет.

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

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

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

вот «настоящий процедурный стиль» существует только в теории. а на практике это и неудобно, и нечитабельно, да ещё и мешает компилятору генерить оптимальный код, чаще всего. а ради чего, собственно, такие мучения? чисто попонтоваться разве что.

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

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

Да, я об этом и пишу. Городить цикл с нулём итераций или написать анонимную функцию только ради того, чтобы не говорить goto — это жесть! Читается хуже, а Дейкстре все равно не соответствует.

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

так компиляхтер заинлайнит эту анонимную функцию и в итоге выхлоп будет такой же как с гото, только код выглядит понтовей :)

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

Ты лучше приведи примеры когда goto не говнокод. Вот я знаю только один пример — выйти из блока кода, но для этого есть оператор break или return в случае функции.

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

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

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

достаточно пару лет пописать на ассемблере и проблем с адресами и переходами уже не будет

Мы писали и на ассемблере. Не пару лет, но год точно, кто то так и до сих пор пишет. Другое дело что понимать как работают переходы и не допускать механических ошибок это две большие разницы.

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

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

А вот это самая большая ошибка всех системщиков ИМХО. Какая разница, как выглядит код для процессора. В идеальном случае всеми мыслимыми и немыслимыми оптимизациями занимается компилятор, а код пишется не для машины, а для разработчиков. Медленный код всегда можно наоптимизировать, воткнуть ассемблерные вставки, если это действительно необходимо, а вот исправить косяки алгоритма и сделать правильную алгоритмическую сложность под нужную задачу гораздо важнее, сложнее и требует читабельности кода.

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

но действительно смотрится элегантнее вложенных проверок.

Ты сам ответил на свой вопрос. Линейная логика читается намного легче ветвистой. Способ линеаризовать - последовательно откоцывать кейзы по кусочку, заканчивая каждый break/continue/return.

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

открой код кернела и поищи поиском goto :)

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

Iron_Bug ★★★★★
()
Последнее исправление: Iron_Bug (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.