LINUX.ORG.RU

Юзкейсы для goto

 ,


0

3

Пародия вот на это.

Вместо вот этого недоразумения

for (i = 0; i < len; i++) {
    if (some_func(arr[i]) == 0) {
        break;
    }
}

можно написать более изящно

for (i = 0; i < len; i++) {
    if (do_something(arr[i]) == 0) {
        goto OUT;
    }
}

OUT:
    do_something_else();


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

А чего ему тут делать? Тред для бытовых нужд.

anonymous
()

goto можно использовать для выразительности кода, иногда оно бывает в тему. Если вам религия не позволяет - обойтись без него можно всегда, но только в высокоуровневом коде. Как уже писали выше, jmp'ы никто не отменял.

men()
{
   goto pub;
  pub:
   return pissed;
}

women()
{
   goto bathroom;
  bathroom:
   while (1) ;
}
Nietzsche
()
Ответ на: комментарий от Vovka-Korovka

Либо я что-то не понял.

В стандарте на Си написано, что использование неинициализированной переменной — undefined behavior. Поэтому компилятор вправе считать, что программа никогда не обломится на первой строчке. И выкинуть проверку для оптимизации.

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

Блин, ну я даже ссылку в начало поста вынес. Даже слово «пародия» добавил.

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

some_func может быть модифицирующей функцией. В этом случае использовать ее внутри std::find_if не комильфо.

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

Только как это к твоему случаю относится? Неинициализированные переменные будут использоваться не в конструкции if, а после - во free.

Vovka-Korovka ★★★★★
()
Ответ на: комментарий от Eddy_Em

Нафиг это? Говно — только С!

anonymous
()

В C и C++:

  • для выхода из вложенных циклов.
  • для организации высоко оптимизированных конечных автоматов (см вывод ragel -G2)

Кроме того, в C goto — один из самых изящных способов организации cleanup-ов в случае ошибки (в C++ RAII с этим замечательно справляется):

if (!init1(obj1))
    goto failure1;
if (!init2(obj2))
    goto failure2;
/* ... */
if (!do_smth(obj1, obj2))
    goto run_failure;
/* ... */
return SUCCESS(obj1, obj2);
run_failure:
  destroy2(obj2);
failure2:
  destory1(obj1);
failure1:
  return FAILURE;
kawaii_neko ★★★★
()
Ответ на: комментарий от invy

Я вообще не понимаю, какого хрена ТС воткнул тег [цеплусплус], если спрашивает про goto! Он бы еще printf в цеплюсплюс потащил!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от xenohunter

Не обращай внимания, он ещё один клоун, вроде того по ссылке, просто с другим фетишем.

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

Именно! А у нас здесь пародия предполагалась. Но получился вброс.

xenohunter
() автор топика
Ответ на: комментарий от Vovka-Korovka

Неинициализированные переменные будут использоваться не в конструкции if, а после - во free.

Правильно. Отсюда компилятор делает вывод, что конcтрукция if либо туда не переходит, либо там происходит что угодно. Для оптимизатора угодно сделать переход обратно, тогда можно считать, что по обеим веткам if перехода не было и выкинуть вообще проверку условия.

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

finally для этого и применяется. А в C# вообще есть конструкция using, которая гарантирует освобождение, при этом не надо писать мусорный код, компилятор добавит вызов финализатора автоматически. Кстати, когда в крестопараше появится сборка мусора (разумеется, с разруливанием цикличсеких ссылок)? Тупые байтослесари до сих пор вручную следят за памятью?

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

Это конструкция сокращает объем кода, повышая его читабельность. Путь нормальных языков программирования - лаконичность, сокращение избыточного синтаксиса, оставление только логики. Путь C/C++ - мусор из инструкций, записанных в непонятном синтаксисе. Сравните код IDE Eclipse на Java, с кодом какой-нибудь Code:Blocks на C++. Поэтому просто смешно, когда байтослесари говорят что-то про говнокод. Хуже крестокода только код на PHP.

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

Отсюда компилятор делает вывод, что конcтрукция if либо туда не переходит, либо там происходит что угодно.

Не, не делает. Вобщем, в твоем примере быдло-код.

Vovka-Korovka ★★★★★
()
Ответ на: комментарий от Den_Zurin

Это конструкция сокращает объем кода, повышая его читабельность

LOL

Путь нормальных языков программирования - лаконичность, сокращение избыточного синтаксиса

Да, но приводить в пример тут Java - LOL

Путь C/C++ - мусор из инструкций, записанных в непонятном синтаксисе

LOL, твоя Java - огрызок от С++.

с кодом какой-нибудь Code:Blocks

Нашел что приводить в пример. Возьми лучше «какой-нибудь blender».

Поэтому просто смешно, когда байтослесари говорят что-то про говнокод. Хуже крестокода только код на PHP.

Смешно, когда жаберы рассуждают про лаконичность.

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

finally для этого и применяется

try {
  File in;
  File out;
  // ... read from in, write to out
} catch (IOException ex) {
} finally {
  in.close();
}
// ouch :D

На плюсах такой факап, при использовании RAII не возможен.

А в C# вообще есть конструкция using

Каких только извращений ненапридумают :D

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

Кстати, когда в крестопараше

Не знаю такого языка.

появится сборка мусора (разумеется, с разруливанием цикличсеких ссылок)?

Не нужно. Чисто там, где не мусорят.

Тупые байтослесари до сих пор вручную следят за памятью?

Может тубые «байтослесари» и следят. А те, кто пишет на c++ - нет.

invy ★★★★★
()
Ответ на: комментарий от Vovka-Korovka

Не, не делает

Имеет право делать. Например, этот код

enum {N = 32};
int a[N], pfx[N];
void prefix_sum (void)
{
  int i, accum;
  for (i = 0, accum = a[0]; i < N; i++, accum += a[i])
    pfx[i] = accum;
}

превращается при оптимизации в

void prefix_sum (void)
{
  int i, accum;
  for (i = 0, accum = a[0]; ; i++, accum += a[i])
    pfx[i] = accum;
}

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

А больше всего рулит внезапно PHP:

break accepts an optional numeric argument which tells it how many nested enclosing structures are to be broken out of.

И никаких лэйблов глазами искать не надо, ты ведь и так при чтении помнишь, на какой ты глубине.

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

вообщет такая рулёжка подтверждение что на пхп всётаки уметь в счёт от 1 до 100 нужно.

однако как и всё в пхп такие выходы их вложенностей(число уровней насколько выскочить) это составная часть фрактала плохого дизайна.

и да вопрос чиста на поржать - там тока константы позволительны али полный содом?

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

ну в 5ю4ю0 отрубили возможность из переменой -пацанов из канализации(пхп всеяден да) обидели.

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

Можно что-то похожее реализовать с помощью goto и макросов.

#define named(blockname) goto blockname; \
                         blockname##_skip: if (0) \
                         blockname:

#define break(blockname) goto blockname##_skip

struct test
{
  std::string str;
  test (std::string s) : str(s) { 
    std::cout << "test::test()::" << str << "\n"; 
  }
  ~test () { 
    std::cout << "~test::" << str << "\n"; 
  }
};

int main(void)
{
  named (outer) 
  for (int i = 0; i < 10; i++)
  {
    test t1("t1");
    int j = 0;
    named(inner)
    for (test t2("t2"); j < 5; j++)
    {
      test t3("t3");
      if (j == 1) break(outer);
      if (j == 3) break(inner);
      test t4("t4");
    }
    std::cout << "after inner\n";
  }
  return 0;
}

Macros are used to hide the explicit use of gotos, which is often frowned upon.

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

До 100? У меня воображения хватает до 3 максимум, дальше уже какая-то совершенно нечитабельная вложенность (нечитабельная для выхода из неё), не грех и в функцию что-то вынести.

greatperson
()

Во такой подход рекомендуют инженеры эдоуби:

do {
    if (! do_1())
        break;

    if (! do_2()
        break;

    /* ... */
} while (0);

cleanup();

Из плюсов: предсказуемость — после break контроль передается только *вниз* по коду. В С++ еще получаем приятную плюшку в виде вызова деструкторов у scope-local переменных.

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

В С++

В C++ за такое можно и канделябром :)

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

Во такой подход рекомендуют инженеры эдоуби:

А потом один вложенный цикл и тебе придется код переписывать. Не говоря о том, что после облома do_1() и do_2() обычно cleanup() должен освобождать разное количество ресурсов - поскольку успешное выполнение do_1() часто захватывает дополнительный ресурс.

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

Там в каждом ифе при провале можно ещё немного подчистить (для каждого специфического случая) а потом break.

В любом случае — мопед не мой...

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

Там в каждом ифе при провале можно ещё немного подчистить

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

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

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

Это если ресурсы «снежным комом» выделяются. Есть ещё ситуации типа выделил -> использовал -> получил новое значение -> почистил

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

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

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

вообщет как раз классический switch (т.е вектор меток) и предназначен когда по мере прохождения предусловий растёт флаг а затем происходит swith_flag_cleanup где просто напросто простынка подчисток разбавленная метками для точного начала

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