Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > оператор перехода goto


Автор: UniBomb 14.12.2006, 21:02
Никогда не использовал и запрет преподавателей на использование оператора воспринимал как должное. Но всё таки интересно, почему не рекомендуется использовать goto в программах? Это чисто эстетические причины или же некорректность в работе оператора?

Автор: JackYF 14.12.2006, 21:05
Это не только эстетические причины. Вообще на эту тема уже столько раз поднималась... воспользуйся поиском.
goto  нарушает естественное течение программы, т.е. невызов нужных конструкторов/деструкторов, запутанность программ...
Минусов очень много. Средства языка позволяет свободно обходиться без goto.

Однозначно false...

Автор: INHazeR 14.12.2006, 21:07
Whenever possible, you should avoid using gotos in your program. They tend to encourage very convoluted code that can be extremely difficult to follow.

As the goto is theoretically unnecessary - there's always an alternative approach to using goto - a significant cadre of programmers say you should never use it. I don't subscribe to such an extreme view. It is a legal statement after all, and there are occasions when it can be convenient. However, I do recommend that you only use it where you can see an obvious advantage over other options that are available.

Автор: MAKCim 14.12.2006, 21:08
чушь, что его нельзя использовать
главное использовать с умом и когда это действительно облегчает понимание кода
в С++, скорее всего, можно обойтись в большинстве случаев без него, в С много моментов, где его применение оправдано
Если есть желание, посмотри исходники http://www.linux-m32r.org/lxr/http/source/ - яркий пример любви к goto  smile

Добавлено @ 21:10 
JackYF
не согласен с тобой, нельзя быть таким категоричным
goto во многих случаях делает код как раз менее запутанным и понятным

Автор: UniBomb 14.12.2006, 21:11
JackYF

Поиском воспользовался, но не нашёл темы с аналогичным названием. Возможно эта тема и раскрывалась в топике с другим вопросом, но перелопачивать из все не представляется приятным занятием...


Цитата

goto  нарушает естественное течение программы, т.е. невызов нужных конструкторов/деструкторов, запутанность программ...



А вот если оператор используется в линейном коде, где нет ни конструкторо/деструкторов и скажем идёт расчёт какой-нибудь системы уравнений, где нельзя однозначно предугадать дальнейшее решение и в этом коде будет проще использовать этот оператор (ну скажем короче, продуктивнее и проще, чем куча ифоф, кейсов, форов и вайлов). В таких случаях тоже низя?

INHazeR

ну вот, сидеть мне теперь со словарём допозна... Единственное что я понял, что оператор теоретически безопасен (?).

MAKCim

 smile 

Автор: apook 14.12.2006, 21:13
Короче на сколько я понимаю этот оператор приводит к ошибкам программы
особенно если код большой а так же если кто-то захочет разобрать
твою прогу (дизассембл) то участок кода напр:
for(  ;; )
{
    ....
   for(  ;;  )
   {
        if( x <4 ) goto ass;
        }   
    }
Вроде-бы сведет на нет его понимание

но я иногда не брезгую хотя не очень он мне тоже нравится

Автор: MAKCim 14.12.2006, 21:14
Цитата

В таких случаях тоже низя? 

если код станет понятнее - однозначно можно
goto, повторюсь, это не табу

Автор: TaNK 14.12.2006, 21:15
goto необходимо использовать при самой необходимости, например когда невозможно использовать оператор break;

Автор: JackYF 14.12.2006, 21:15
Unexpected returnvalue 2 from Glimpse - вот ответ на поиск 'goto' в тексте(ссылка Makcim'a). )))


Цитата(MAKCim @  14.12.2006,  21:08 Найти цитируемый пост)
чушь, что его нельзя использовать


Очень опасно. Особенно в С++.
Я лично на С ничего не пишу и не собираюсь.

Автор: MAKCim 14.12.2006, 21:15
UniBomb
пример чего?

Автор: UniBomb 14.12.2006, 21:16
apook

Цитата

 а так же если кто-то захочет разобрать
твою прогу (дизассембл) то участок кода напр:


Допустим исходники только для твоих глаз, причём очень хорошо закоментирована.

Автор: INHazeR 14.12.2006, 21:17
если оператор в языке существует, значит использовать его можно и нужно, если того требует ситуация. другое дело, что я даже гипотетически не могу представить себе ситуацию, когда этот оператор был бы незаменим. гораздо проще и надежнее использовать условия и циклы. ИМХО.

Автор: UniBomb 14.12.2006, 21:18
MAKCim

Ну... да нет, просто думал есть где-нить под рукой кусок кода, где он действительно оправдан...

Автор: MAKCim 14.12.2006, 21:18
Цитата

Очень опасно. Особенно в С++.

Вообще, С++, если разобраться, очень опасный язык
Мое имхо, все, что к месту - хорошо, goto в том числе
ничего плохого в нем нет

Добавлено @ 21:24 
Цитата

Ну... да нет, просто думал есть где-нить под рукой кусок кода, где он действительно оправдан... 

Код

/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
1072 static int fastcall do_path_lookup(int dfd, const char *name,
1073                                 unsigned int flags, struct nameidata *nd)
1074 {
1075         int retval = 0;
1076         int fput_needed;
1077         struct file *file;
1078 
1079         nd->last_type = LAST_ROOT; /* if there are only slashes... */
1080         nd->flags = flags;
1081         nd->depth = 0;
1082 
1083         if (*name=='/') {
1084                 read_lock(&current->fs->lock);
1085                 if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) {
1086                         nd->mnt = mntget(current->fs->altrootmnt);
1087                         nd->dentry = dget(current->fs->altroot);
1088                         read_unlock(&current->fs->lock);
1089                         if (__emul_lookup_dentry(name,nd))
1090                                 goto out; /* found in altroot */
1091                         read_lock(&current->fs->lock);
1092                 }
1093                 nd->mnt = mntget(current->fs->rootmnt);
1094                 nd->dentry = dget(current->fs->root);
1095                 read_unlock(&current->fs->lock);
1096         } else if (dfd == AT_FDCWD) {
1097                 read_lock(&current->fs->lock);
1098                 nd->mnt = mntget(current->fs->pwdmnt);
1099                 nd->dentry = dget(current->fs->pwd);
1100                 read_unlock(&current->fs->lock);
1101         } else {
1102                 struct dentry *dentry;
1103 
1104                 file = fget_light(dfd, &fput_needed);
1105                 retval = -EBADF;
1106                 if (!file)
1107                         goto out_fail;
1108 
1109                 dentry = file->f_dentry;
1110 
1111                 retval = -ENOTDIR;
1112                 if (!S_ISDIR(dentry->d_inode->i_mode))
1113                         goto fput_fail;
1114 
1115                 retval = file_permission(file, MAY_EXEC);
1116                 if (retval)
1117                         goto fput_fail;
1118 
1119                 nd->mnt = mntget(file->f_vfsmnt);
1120                 nd->dentry = dget(dentry);
1121 
1122                 fput_light(file, fput_needed);
1123         }
1124         current->total_link_count = 0;
1125         retval = link_path_walk(name, nd);
1126 out:
1127         if (likely(retval == 0)) {
1128                 if (unlikely(current->audit_context && nd && nd->dentry &&
1129                                 nd->dentry->d_inode))
1130                 audit_inode(name, nd->dentry->d_inode, flags);
1131         }
1132 out_fail:
1133         return retval;
1134 
1135 fput_fail:
1136         fput_light(file, fput_needed);
1137         goto out_fail;
1138 }

просто пример из ядра, не скажу, однако, что тут без goto не обойтись

Автор: JackYF 14.12.2006, 21:25
Вообщем, я уже 3 года обхожусь без goto.
По сему считаю, что его нужно применять только в случае крайней необходимости.

К пример, выход из двойного и даже тройного цикла не считаю такой крайней необходимостью.

Это лично мое мнение, никому навязывать не собираюсь.


Автор: Gen 14.12.2006, 21:27
Вопрос - а много ли он сжирает ресурсов по сравнению с готозаменяющими циклами?? smile 

Автор: INHazeR 14.12.2006, 21:31
гм. как goto может сжирать ресурсы? это же команда

Автор: codelord 14.12.2006, 21:32
в книге K&R об этом уже давно написали.
коротко:
ничего криминального, не обязательно, всегда можно обойтись.
сам давно уже не пользовался. Хотя когда еще в школе на бейсике то всегда

фрагмент K&R

Цитата

      в языке "c" предусмотрен и  оператор  goto,  которым
  бесконечно  злоупотребляют,  и  метки  для  ветвления.  С
                           - 127 -
  
  формальной точки зрения оператор goto никогда не является
  необходимым, и на практике почти  всегда  можно  обойтись
  без него. Мы не использовали goto в этой книге.
       Тем не менее,  мы  укажем  несколько  ситуаций,  где
  оператор  goto   может   найти   свое   место.   Наиболее
  характерным является его использование тогда, когда нужно
  прервать  выполнение  в   некоторой   глубоко   вложенной
  структуре, например, выйти сразу из  двух  циклов.  Здесь
  нельзя непосредственно использовать оператор  brеак,  так
  как он прерывает только самый внутренний цикл. Поэтому:
         for ( ... )
                 for ( ... )     {
                         ...
                         if (disaster)
                                 goto error;
                 }
         ...
 error:
         clean up the mess
  Если программа обработки  ошибок  нетривиальна  и  ошибки
  могут возникать в нескольких местах, то такая организация
  оказывается удобной. Метка имеет такую же  форму,  что  и
  имя переменной, и за ней всегда следует двоеточие.  Метка
  может быть приписана к любому оператору той же функции, в
  которой находится оператор goto.
       В  качестве  другого   примера   рассмотрим   задачу
  нахождения первого отрицательного  элемента  в  двумерном
  массиве. (Многомерные массивы рассматриваются в главе 5).
  Вот одна из возможностей:
                           - 128 -
         
          for (i = 0; i < n; i++)
                 for (j = 0; j < m; j++)
                         if (v[i][j] < 0)
                             goto found;
                 /* didn't find */
         ...
 found:
         /* found one at position i, j */
         ...
       Программа, использующая оператор goto, всегда  может
  быть  написана  без  него,  хотя,   возможно,   за   счет
  повторения некоторых проверок и  введения  дополнительных
  переменных. Например, программа поиска в  массиве  примет
  вид:
         found = 0;
         for (i = 0; i < n && ]found; i++)
                 for (j = 0; j < m && ]found; j++)
                         found = v[i][j] < 0;
         if (found)
                 /* it was at i-1, j-1 */
                 ...
         else
                 /* not found */
                 ...
       Хотя мы не являемся в этом вопросе догматиками,  нам
  все же кажется, что если и  нужно  использовать  оператор
  goto, то весьма умеренно.



Автор: Gen 14.12.2006, 21:38
Цитата

гм. как goto может сжирать ресурсы? это же команда


Сформулирую вопрос по другому - целесообразно ли использовать его постоянные вызовы в цикле, если, например, это делает код более читаемым??

Автор: Dray 14.12.2006, 21:41
Цитата(Gen @  14.12.2006,  21:38 Найти цитируемый пост)
это делает код более читаемым?? 

Ну раз так, почему нет?
Если побочных эффектов не вылезет, - используй.

Автор: witex 14.12.2006, 21:44
goto  ваабще смысла нету использовать.

Использование функций всегда заменяет goto. Тем более что использоване функций, делает значимо читабильным код, чем с goto

Автор: MAKCim 14.12.2006, 21:46
Цитата

Использование функций всегда заменяет goto. Тем более что использоване функций, делает значимо читабильным код, чем с goto 

call != jmp

Автор: witex 14.12.2006, 21:49
понятно дело, что так и есть! Но я встречал столько кадров которые пытались заменить функции оператором goto

Автор: MAKCim 14.12.2006, 21:52
Цитата

понятно дело, что так и есть!

к чему тогда
Цитата

Использование функций всегда заменяет goto.

Автор: GrayCardinal 14.12.2006, 21:53
UniBomb

ИМХО
Оператор "goto" нельзя использовать по той же самой причине по какой в Советском Союзе нельзя было ездить на одном рельсе.
/ИМХО

Автор: nikitao 14.12.2006, 22:02
Про goto - это боян , который появился пожалуй сразу с появлением языков высокого уровня. О нем спорили и спорить будут smile  , но обычно оппоненты приводят неправильные аргументы и вообще спорят не о том. Те, кто кричат против goto , обычно говорят, что большое их количество приводят к трудновыполнимым ошибкам , трудно читаемому коду и прочие, когда как сторонники говорят о его малом использовании в редких, специфических местах. Это же разные вещи smile

Если вкратце , то моя позиция такая ( хотя я goto не юзал года 3 уже) : Если на тебе резиновые сапоги, то зачем обходить три квартала, чтобы не промочить ноги?



ЗЫ Когда создавался ЯП Ада ( признаный самым продуманным ЯП ) , то шли долгие дискуссии на эту тематику и в результате goto все же было включить в него smile

Добавлено @ 22:03 
GrayCardinal, слишком громкое заявление. имхо.


С другой стороны я пожалуй соглашусь с Void , который говорил , что goto при правильном проектировании просто не нужен. 
Отсутствие goto должно стать для программиста не целью , а  результатом накопления им опыта ) 

Автор: GrayCardinal 14.12.2006, 22:13
nikitao
Так ясно что ИМХО, или дописать ?  smile 

Автор: nikitao 14.12.2006, 22:25
Цитата(GrayCardinal @  14.12.2006,  23:13 Найти цитируемый пост)

Так ясно что ИМХО, или дописать ?  smile  

Извени , не уверен , что вопрос понял smile  но в любом случае лучше дописать smile 

Автор: GrayCardinal 14.12.2006, 22:52
nikitao
Так нормалек ?

Добавлено @ 23:00 
ЗЫ
А будем обсуждать можно ли использовать обе ?
 smile  smile  smile 

Автор: UniBomb 14.12.2006, 23:05
nikitao

Цитата

С другой стороны я пожалуй соглашусь с Void , который говорил , что goto при правильном проектировании просто не нужен. 
Отсутствие goto должно стать для программиста не целью , а  результатом накопления им опыта ) 


Ты опять таки возвращаешся к вопросу об эстетики, имхо программиста меньше всего должно беспокоить наличие оператора (если это конечно не приводит к ошибке) goto. Прочтя все высказывания я понял одно - программиста от "кулхацкера" отличает как раз ниличие или отсутвие goto в коде их программ. С этой же точки зрения можно забанить функцию ReadFileEx, когда есть такая замечательная функция ReadFile (это просто пример, взял первые попавшие на ум похожие функции). А то что такие программы трудно читать - это проблемы того, кто читает (хотя я всё таки за "правила хорошего тона" и стараюсь писать удобочитаемый код). Моё ИМХО - если оператор или функция не вызывает ошибки, то её нужно использовать эти операторы или функции в случае максимального комфорта...


Gen
Dray
к слову - а что значат картинки у вас в подписях?

Автор: apook 14.12.2006, 23:17
Вот статья как Умные дядьки изгнали GOTO из одного языка

Автор: nikitao 15.12.2006, 00:00
Цитата(UniBomb @  15.12.2006,  00:05 Найти цитируемый пост)
то что такие программы трудно читать - это проблемы того, кто читает

Жесть.. smile ... Без комментариев. 


GrayCardinal,  smile 

Автор: UniBomb 15.12.2006, 00:07
nikitao

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

Автор: Rockie 15.12.2006, 01:21
Цитата(UniBomb @  14.12.2006,  21:11 Найти цитируемый пост)
ну вот, сидеть мне теперь со словарём допозна... Единственное что я понял, что оператор теоретически безопасен


Это если теоретически написать программу smile

Цитата(apook @  14.12.2006,  21:13 Найти цитируемый пост)
твою прогу (дизассембл) то участок кода напр:

как насчет тегов кода, запятых и полных слов? =) С примером согласен.

Цитата(JackYF @  14.12.2006,  21:25 Найти цитируемый пост)
К пример, выход из двойного и даже тройного цикла не считаю такой крайней необходимостью.


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

Цитата(nikitao @  14.12.2006,  22:02 Найти цитируемый пост)
Про goto - это боян

 smile 

Цитата(UniBomb @  15.12.2006,  00:07 Найти цитируемый пост)
Спасение утопающик - дело рук самих утопающих (или как то так...).

Цитата(UniBomb @  14.12.2006,  23:05 Найти цитируемый пост)
 Прочтя все высказывания я понял одно - программиста от "кулхацкера" отличает как раз ниличие или отсутвие goto в коде их программ.
Цитата
А то что такие программы трудно читать - это проблемы того, кто читает


UniBomb, могут стать твои, если тебя уволят smile.
imho программиста от кулхацкера отличает наличие или отсутствие уважения к коллегам, которые твой код смотрят и с ним работают. Программа может быть написана грамотно и умно с точки зрения того, кто ее писал и быть абсолютным г@#;ом для остальных. И дело тут не в goto а в отношении.


Автор: UniBomb 15.12.2006, 11:54
Rockie

Цитата

mho программиста от кулхацкера отличает наличие или отсутствие уважения к коллегам, которые твой код смотрят и с ним работают. Программа может быть написана грамотно и умно с точки зрения того, кто ее писал и быть абсолютным г@#;ом для остальных. И дело тут не в goto а в отношении.


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

Автор: Любитель 15.12.2006, 11:56
В C даже сомнения нету. Если не извращаться, а осмысленно использовать, то это нормальный и естественный оператор, который не только усложняет восприятие кода, но и упрощает его. В плюсах - лучше воздержаться. Есть множество альтернатив, а goto в плюсах всё же не безопасен.

Автор: UnrealMan 15.12.2006, 13:00
Цитата(JackYF @  14.12.2006,  21:05 Найти цитируемый пост)
goto  нарушает естественное течение программы, т.е. невызов нужных конструкторов/деструкторов

А поподробней можно?

Автор: maxim1000 15.12.2006, 13:13
касательно невызывания конструкторов/деструкторов при использовании goto
это не свсем так:
если с помощью goto происходит выход из области видимости объекта, его деструктор вызывается
в то же время не допускается использование goto, которое приводит к пропуску конструкторов
P.S.
не то, чтобы я за него агитировал, но и лишнего ему приписывать не надо smile

Автор: JackYF 15.12.2006, 16:23
Цитата(maxim1000 @  15.12.2006,  13:13 Найти цитируемый пост)
если с помощью goto происходит выход из области видимости объекта, его деструктор вызывается


Наверное, ты прав.

Автор: SaDFromSpb 15.12.2006, 23:07
Что касается меня, то с тех пор, как препод нам давным давно сказал, что goto - это от дьявола, и что использующий его да будет гореть в геене огненной, так ни разу им и не воспользовался. Считаю, что код можно сделать красивым и удобочитаемым без оператора goto, уж по крайней мере в С++.
По поводу ядра линукс: его пишут особые люди с особым складом программистского ума =). Если начинать прогать с asm'а =), то отказ от оператора goto сперва покажется чем-то диким, наверное. (Хотя кто в наши времена начинает с asm'а? =) )

Эта тема, действительно, может превратиться в долгий флуд, и я не стал бы сюда постить, если бы не вспомнил про одну интересную статейку, в которой представляется чудесный способ избавления от трудных мест в алгоритме со многочисленными ветвлениями и "внезапными" выходами по среди тел воложенных циклов.
http://www.codenet.ru/progr/alg/algoritm.php
Эта статья, я думаю, будет особо полезна тем, кто считает, что в некоторых случаях goto - панацея.

П.С.: Прошу заметить, что ярым противником goto не являюсь. Хотя был бы неприятно удивлен увидеть его в коде матерого прикладного приложения, написанного на оо языке. Когда он действительно вреден, так это когда его используют начинающие, вместо того, чтобы лучше продумать заковыристый кусок алгоритма.

Автор: UnrealMan 16.12.2006, 11:20
Цитата(maxim1000 @  15.12.2006,  13:13 Найти цитируемый пост)
если с помощью goto происходит выход из области видимости объекта, его деструктор вызывается

Цитата(JackYF @  15.12.2006,  16:23 Найти цитируемый пост)
Наверное, ты прав.

Не наверное, а точно:

Цитата(ISO/IEC 14882:2003(E) 6.6 Jump statements)
On exit from a scope (however accomplished), destructors (12.4) are called for all constructed objects with automatic storage duration (3.7.2) (named objects or temporaries) that are declared in that scope, in the reverse order of their declaration. Transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction of variables with automatic storage duration that are in scope at the point transferred from but not at the point transferred to.

Цитата(maxim1000 @  15.12.2006,  13:13 Найти цитируемый пост)
в то же время не допускается использование goto, которое приводит к пропуску конструкторов

Пропуску любой инициализации вообще:

Цитата(ISO/IEC 14882:2003(E) 6.7 Declaration statement)
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer (8.5).

[Example:
Код
void f()
{
    // ...
    goto lx; // ill-formed: jump into scope of a
    // ...
ly:
    X a = 1;
    // ...
lx:
    goto ly; // OK, jump implies destructor
    // call for a followed by construction
    // again immediately following label ly
}
—end example]

Цитата(maxim1000 @  15.12.2006,  13:13 Найти цитируемый пост)
но и лишнего ему приписывать не надо 

Вот-вот.

Автор: FelikZ 16.12.2006, 16:58
По-моему в малом количестве в некоторых специфических задачах
вполне можно употреблять без всяких сомнений...

Автор: zabivator 16.12.2006, 17:08
Читал тему, с кем-то согласен, с кем-то не очень.
Один момент! Вот представьте себе, что идет обход дерева через рекурсивный вызов метода...допустим, для поиска определенного элемента. Использование goto либо кидание исключения мне кажется куда более гуманным, чем традиционные методы.

Автор: vinter 17.12.2006, 00:32
по мне так goto - зло для человека, который читает чужой(большой) код, особенно если goto кидает куда-нить за пределы видимой страницы.. натерпелся с этими метками в асме, в С\С++ ни разу не использовал(надеюсь и не буду) и живу нормально..
 smile 
P.S народ че случилось с аватарами некоторых участников, я народ путаю.. smile 

Автор: bel_nikita 17.12.2006, 02:22
Цитата(nikitao @ 14.12.2006,  21:02)
С другой стороны я пожалуй соглашусь с Void , который говорил , что goto при правильном проектировании просто не нужен. 
Отсутствие goto должно стать для программиста не целью , а  результатом накопления им опыта )

считаю наоборот smile Использование оператора goto результат опытности и зрелости smile А то, что нарушает читабельность кода, то это проблема не goto, а кривых рук и недокументирования кода. По опыту копания в чужих листингах можно сказать: что и без оператора goto можно написать так, что хрен поймешь что у человека было в голове, чем он думал и что курил, когда писал код. И в тоже время можно увидеть код с goto, который читается, как интересная книга, на одном дыхании


З.Ы.: Если профессор на лекциях говорит студентам, что goto - от дьявола, правду говорит, дабы уберечь молодой организм от злоупотребления и заставить задуматься над проектированием. Но потом, через пару лет, при определенных обстоятельствах, вы вспомните о всемогущем goto и все же используете его... но это уже будет не зеленый студент, а зрелый программист smile 

Автор: AlexPro 17.12.2006, 13:26
Хотел тоже высказаться, но после K&R остается только дабавить : Аминь!

Цитата(SaDFromSpb @  16.12.2006,  07:07 Найти цитируемый пост)
(Хотя кто в наши времена начинает с asm'а? =) 

 smile Ну, вот он я!
Хотя не знаю, 10-15 лет назад - это можно еще относить к нашим временам? smile 

Цитата(SaDFromSpb @  16.12.2006,  07:07 Найти цитируемый пост)
Если начинать прогать с asm'а =), то отказ от оператора goto сперва покажется чем-то диким, наверное.

В этом плане у меня довольно интересный опыт: после ассемблера я перешел на FoxPro. В виду полного отсутствия операторов перехода, мне пришлось поневоле от них отказаться. После ассемблера с его десятками операторов перехода, отсутствие их в Фоксе поначалу приводило в ступор. Так что имеется опыт как интенсивого использования операторов перехода, так и полного отказа от них.

В проекте, над которым я сейчас работаю (20К строк) оператор goto используется ровно пять раз. Каждое его использование обусловлено соображениями производительности и (или) читаемости кода (т.е. использование оператора приводило к упрощению кода). Везде операторы и метки перехода находятся в пределах одного экрана.

Что, собственно, я этим хотел сказать? Да ровно то, что уже сказали Керниган и Ричи: оператор можно использовать, но если это действительно нужно.

Автор: Kirill89 17.12.2006, 17:17
Я может быть немного не по теме, но как например в visual basic без goto обойтись? например on error goto <метка>.

Автор: Anikmar 17.12.2006, 23:41
А при чем здесь форум С++ ?

Автор: Kirill89 18.12.2006, 00:07
Цитата(Anikmar @  17.12.2006,  23:41 Найти цитируемый пост)
А при чем здесь форум С++ ? 

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

Автор: UniBomb 18.12.2006, 13:31
bel_nikita

Вот это действительно аминь...  


Anikmar
Kirill89

Вероятно автор топика имел в виду использование оператора в программах c/cpp. Хотя кто его знает smile

Автор: Voldemar2004 18.12.2006, 13:38
Цитата(Kirill89 @  17.12.2006,  18:17 Найти цитируемый пост)
как например в visual basic без goto обойтись? например on error goto <метка>.
Цитата(UniBomb @  18.12.2006,  14:31 Найти цитируемый пост)
Вероятно автор топика имел в виду использование оператора в программах c/cpp. Хотя кто его знает 
 smile Имхо, всегда goto можно избежать при грамотном подходе, даже в ущерб производительности, зато решение будет красивее.

А в VB 
Код
on error goto <метка>
 - стандрат языка, причем очень удобный.



Автор: Anikmar 18.12.2006, 14:09
Цитата(Voldemar2004 @ 18.12.2006,  13:38)
 smile Имхо, всегда goto можно избежать при грамотном подходе, даже в ущерб производительности, зато решение будет красивее.


И наоборот. С goto иногда получается красивее и быстрее.

Блин, я тоже в этот баян втянулся...  smile 

Я в своем проекте использую goto целых 3 раза и не собираюсь ничего выдумывать, чтобы его от туда вымарать - он там логично сидит, никому не мешает, ничего не нарушает, а городить хренову тучу отступов и скобок не вижу смысла. Тем более использовать throw... Нормальный оператор. Расширяет возможности языка. 

Все лежит на совести программера. Как говорится с дури и х... сломать можно.

Автор: UniBomb 19.12.2006, 00:12
Anikmar

Вот! Вот оно!! Всё таки есть те, кто считает нормальным использовать оператор и те, кто считает это злом...

кстати, отсюда следует правило - хороший баян заразителен smile

Автор: SergeCpp 20.12.2007, 14:54
Пожалуй, будет интересен некий исторический экскурс в тему

Вот с такой вот стороны

user posted image
user posted image

И вот с такой вот

http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf

user posted image

Автор: Lazin 20.12.2007, 15:01
я использовал goto всего 2 раза в жизни:
1 раз в программе на С, там это к месту было...
2 раз в программе на паскале, курсе эдак на первом))

Добавлено через 1 минуту и 27 секунд
вообще считаю что можно, но не больше одного goto на ф-ю, иначе код читать станет невозможно...

Автор: SaDFromSpb 20.12.2007, 15:18
Цитата(zabivator @  16.12.2006,  17:08 Найти цитируемый пост)
Читал тему, с кем-то согласен, с кем-то не очень.
Один момент! Вот представьте себе, что идет обход дерева через рекурсивный вызов метода...допустим, для поиска определенного элемента. Использование goto либо кидание исключения мне кажется куда более гуманным, чем традиционные методы. 

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

В Java вообще оператора goto нет. (Хотя слово goto зарезервировано - использовать его нельзя). Посправшивайте в ветке о Java на сколько сильно они от этого страдают  smile 

ЗЫ. Ну нифига вы бородатую тему подняли из праха  =)

Автор: zkv 20.12.2007, 15:20
Цитата(Lazin @  20.12.2007,  15:01 Найти цитируемый пост)
но не больше одного goto на ф-ю, иначе код читать станет невозможно... 

может не более одного label'a? 
Код

int F( int x )
{
//...
  if( xz1 )
    goto l_Error;
//...
  if( xz2 )
    goto l_Error;
//...
  return Ok;
//...
 l_Error:
  //обработка
 return Error;
}

Автор: Lazin 20.12.2007, 15:40
Цитата(zkv @  20.12.2007,  15:20 Найти цитируемый пост)
может не более одного label'a? 

ага
так как логику работы этого
Код

int F( int x )
{
 l_begin:
//...
  if( xz1 )
    goto l_Error;
//...
  if( xz2 )
    goto l_begin;
//...
  return Ok;
//...
 l_Error:
  //обработка
 return Error;
}

уже не переварить

Автор: Cycle 21.12.2007, 00:17
А исключения это уже сложно? Люди стараются придумывают замену goto для вас, а вы... smile

Автор: MAKCim 21.12.2007, 00:31
goto - вещь полезная и во многих случаях оправдана
очень полезна в управлении ресурсами в структурных языках типа С
здесь возможна замена goto функциями, но код будет менее эффективен и логичен
долой предрассудки!  smile

Добавлено через 1 минуту и 6 секунд
Цитата(Cycle @  21.12.2007,  00:17 Найти цитируемый пост)
А исключения это уже сложно?

не всегда оправдано
исключения - крайне тяжеловесный механизм
для прикладной логики самое то, но для критичных участков не подойдет

Автор: sgrey 21.12.2007, 06:15
если goto не нарушает естественного хода программы (т.е. нет скачков вверх кода) то вполне можно его использовать, конечно же с умом и не пихать везде где можно... особенно учитывая что практически в любом случае можно обойтись и без него... 

Автор: xvr 21.12.2007, 16:05
Цитата(UniBomb @ 14.12.2006,  21:02)
Никогда не использовал и запрет преподавателей на использование оператора воспринимал как должное. Но всё таки интересно, почему не рекомендуется использовать goto в программах? Это чисто эстетические причины или же некорректность в работе оператора?

Вообще то не рекомендуется, ну например так:
Код

int
recog_1 (x0, insn, pnum_clobbers)
     register rtx x0;
     rtx insn;
     int *pnum_clobbers;
{
  register rtx *ro = &recog_operand[0];
  register rtx x1, x2, x3, x4, x5;
  int tem;

  x1 = XEXP (x0, 1);
  if (GET_MODE (x1) != SImode)
    goto ret0;
  switch (GET_CODE (x1))
    {
    case ASHIFT:
      goto L80;
    case IOR:
      goto L59;
    case AND:
      goto L73;
    case NOT:
      goto L561;
    case NEG:
      goto L600;
    case HIGH:
      goto L715;
    case EQ:
    case NE:
    case LT:
    case LE:
    case GE:
    case GT:
    case LTU:
    case LEU:
    case GEU:
    case GTU:
      if (relop (x1, SImode))
    {
      ro[1] = x1;
      goto L551;
    }
    }
  L555:
  if (even_relop (x1, SImode))
    {
      ro[1] = x1;
      goto L556;
    }
  if (odd_relop (x1, SImode))
    {
      ro[1] = x1;
      goto L583;
    }
  goto ret0;

  L80:
  x2 = XEXP (x1, 0);
  switch (GET_CODE (x2))
    {
    case ZERO_EXTRACT:
      if (GET_MODE (x2) == SImode && 1)
    goto L81;
      break;
    case CONST_INT:
      if (XWINT (x2, 0) == -1 && 1)
    goto L55;
    }
  goto ret0;

  L81:
  x3 = XEXP (x2, 0);
  if (register_operand (x3, SImode))
    {
      ro[1] = x3;
      goto L82;
    }
  goto ret0;

  L82:
  x3 = XEXP (x2, 1);
  if (GET_CODE (x3) == CONST_INT && int5_operand (x3, SImode))
    {
      ro[2] = x3;
      goto L83;
    }
  goto ret0;

  L83:
  x3 = XEXP (x2, 2);
  if (GET_CODE (x3) == CONST_INT && int5_operand (x3, SImode))
    {
      ro[3] = x3;
      goto L84;
    }
  goto ret0;

  L84:
  x2 = XEXP (x1, 1);
  if (GET_CODE (x2) == CONST_INT && int5_operand (x2, SImode))
    {
      ro[4] = x2;
      if (INTVAL (operands[2]) + INTVAL (operands[3]) + INTVAL (operands[4]) == 32)
    return 12;
      }
  goto ret0;

  L55:
  x2 = XEXP (x1, 1);
  if (register_operand (x2, SImode))
    {
      ro[1] = x2;
      return 8;
    }
  goto ret0;

  L59:
  x2 = XEXP (x1, 0);
  if (GET_MODE (x2) != SImode)
    goto ret0;
  if (GET_CODE (x2) == ASHIFT && 1)
    goto L60;
  if (register_operand (x2, SImode))
    {
      ro[1] = x2;
      goto L67;
    }
  goto ret0;

  L60:
  x3 = XEXP (x2, 0);
  if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == -1 && 1)
    goto L61;
  goto ret0;

  L61:
  x3 = XEXP (x2, 1);
  if (register_operand (x3, SImode))
    {
      ro[1] = x3;
      goto L62;
    }
  goto ret0;

  L62:
  x2 = XEXP (x1, 1);
  if (register_operand (x2, SImode))
    {
      ro[2] = x2;
      return 9;
    }
  goto ret0;

  L67:
  x2 = XEXP (x1, 1);
  if (GET_MODE (x2) == SImode && GET_CODE (x2) == ASHIFT && 1)
    goto L68;
  goto ret0;

  L68:
  x3 = XEXP (x2, 0);
  if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == -1 && 1)
    goto L69;
  goto ret0;

  L69:
  x3 = XEXP (x2, 1);
  if (register_operand (x3, SImode))
    {
      ro[2] = x3;
      return 10;
    }
  goto ret0;

  L73:
  x2 = XEXP (x1, 0);
  if (GET_MODE (x2) == SImode && GET_CODE (x2) == ASHIFT && 1)
    goto L74;
  goto ret0;

  L74:
  x3 = XEXP (x2, 0);
  if (register_operand (x3, SImode))
    {
      ro[1] = x3;
      goto L75;
    }
  goto ret0;

  L75:
  x3 = XEXP (x2, 1);
  if (GET_CODE (x3) == CONST_INT && int5_operand (x3, SImode))
    {
      ro[2] = x3;
      goto L76;
    }
  goto ret0;

  L76:
  x2 = XEXP (x1, 1);
  if (immediate_operand (x2, SImode))
    {
      ro[3] = x2;
      if (mak_mask_p (INTVAL (operands[3]) >> INTVAL (operands[2])))
    return 11;
      }
  goto ret0;

  L561:
  x2 = XEXP (x1, 0);
  if (odd_relop (x2, SImode))
    {
      ro[1] = x2;
      goto L562;
    }
  goto ret0;

  L562:
  x3 = XEXP (x2, 0);
  if (register_operand (x3, CCEVENmode))
    {
      ro[2] = x3;
      goto L563;
    }
  goto ret0;

  L563:
  x3 = XEXP (x2, 1);
  if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1)
    return 74;
  goto ret0;

  L600:
  x2 = XEXP (x1, 0);
  if (GET_MODE (x2) != SImode)
    goto ret0;
  if (GET_CODE (x2) == NOT && 1)
    goto L601;
  if (relop (x2, SImode))
    {
      ro[1] = x2;
      goto L589;
    }
  L594:
  if (even_relop (x2, SImode))
    {
      ro[1] = x2;
      goto L595;
    }
  if (odd_relop (x2, SImode))
    {
      ro[1] = x2;
      goto L626;
    }
  goto ret0;

  L601:
  x3 = XEXP (x2, 0);
  if (odd_relop (x3, SImode))
    {
      ro[1] = x3;
      goto L602;
    }
  goto ret0;

  L602:
  x4 = XEXP (x3, 0);
  if (register_operand (x4, CCEVENmode))
    {
      ro[2] = x4;
      goto L603;
    }
  goto ret0;

  L603:
  x4 = XEXP (x3, 1);
  if (GET_CODE (x4) == CONST_INT && XWINT (x4, 0) == 0 && 1)
    return 79;
  goto ret0;

  L589:
  x3 = XEXP (x2, 0);
  if (register_operand (x3, CCmode))
    {
      ro[2] = x3;
      goto L590;
    }
  goto L594;

  L590:
  x3 = XEXP (x2, 1);
  if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1)
    return 77;
  goto L594;

  L595:
  x3 = XEXP (x2, 0);
  if (register_operand (x3, CCEVENmode))
    {
      ro[2] = x3;
      goto L596;
    }
  goto ret0;

  L596:
  x3 = XEXP (x2, 1);
  if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && 1)
    return 78;
  goto ret0;

  L626:
  x3 = XEXP (x2, 0);
  if (register_operand (x3, CCEVENmode))
    {
      ro[2] = x3;
      goto L627;
    }
  goto ret0;

  L627:
  x3 = XEXP (x2, 1);
  if (GET_CODE (x3) == CONST_INT && XWINT (x3, 0) == 0 && pnum_clobbers != 0 && 1)
    {
      *pnum_clobbers = 1;
      return 81;
    }
  goto ret0;

  L715:
  x2 = XEXP (x1, 0);
  if (GET_MODE (x2) == SImode && GET_CODE (x2) == UNSPEC && XINT (x2, 1) == 0 && XVECLEN (x2, 0) == 1 && 1)
    goto L716;
  goto ret0;

  L716:
  x3 = XVECEXP (x2, 0, 0);
  if (GET_CODE (x3) == LABEL_REF && 1)
    goto L717;
  goto ret0;

  L717:
  x4 = XEXP (x3, 0);
  ro[1] = x4;
  return 103;

  L551:
  x2 = XEXP (x1, 0);
  if (register_operand (x2, CCmode))
    {
      ro[2] = x2;
      goto L552;
    }
  goto L555;

  L552:
  x2 = XEXP (x1, 1);
  if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1)
    return 72;
  goto L555;

  L556:
  x2 = XEXP (x1, 0);
  if (register_operand (x2, CCEVENmode))
    {
      ro[2] = x2;
      goto L557;
    }
  goto ret0;

  L557:
  x2 = XEXP (x1, 1);
  if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && 1)
    return 73;
  goto ret0;

  L583:
  x2 = XEXP (x1, 0);
  if (register_operand (x2, CCEVENmode))
    {
      ro[2] = x2;
      goto L584;
    }
  goto ret0;

  L584:
  x2 = XEXP (x1, 1);
  if (GET_CODE (x2) == CONST_INT && XWINT (x2, 0) == 0 && pnum_clobbers != 0 && 1)
    {
      *pnum_clobbers = 1;
      return 76;
    }
  goto ret0;
 ret0: return -1;
}

Файл insn-recog.c из gcc

Автор: Mayk 21.12.2007, 16:11
Цитата(xvr @  21.12.2007,  20:05 Найти цитируемый пост)

Вообще то не рекомендуется, ну например так:

Это сгенерированный код. В сгенерированном коде читабельность занимает последнее место. имхо. 

Автор: xvr 21.12.2007, 18:30
Цитата(Mayk @ 21.12.2007,  16:11)
Цитата(xvr @  21.12.2007,  20:05 Найти цитируемый пост)

Вообще то не рекомендуется, ну например так:

Это сгенерированный код. В сгенерированном коде читабельность занимает последнее место. имхо.

Проблема в том, что иногда ТАК пишут и руками - вот для таких 'умельцев' и запрещают пользоваться goto. Нормальный вменяемый программист пользуется goto только там, где это действительно надо (т.е. почти нигде smile )

Автор: MAKCim 21.12.2007, 23:42
Цитата(xvr @  21.12.2007,  18:30 Найти цитируемый пост)
Нормальный вменяемый программист пользуется goto только там, где это действительно надо (т.е. почти нигде smile )

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

Автор: SaDFromSpb 22.12.2007, 07:21
Цитата(Cycle @  21.12.2007,  00:17 Найти цитируемый пост)
А исключения это уже сложно? Люди стараются придумывают замену goto для вас, а вы... smile 

Цитата(MAKCim @  21.12.2007,  00:31 Найти цитируемый пост)
не всегда оправдано
исключения - крайне тяжеловесный механизм
для прикладной логики самое то, но для критичных участков не подойдет 


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


Автор: MAKCim 22.12.2007, 10:43
Цитата(SaDFromSpb @  22.12.2007,  07:21 Найти цитируемый пост)
Не только поэтому. Исключения - это только для исключительных ситуаций. Уж лучше использовать goto, вместо того чтобы использовать исключения, как элемент логики программы при ее нормальной работе.

goto в подавляющем большинстве случаев используется именно как средство управления ресурсами в исключительных ситуациях
я, честно говоря, не видел, чтобы где-нибудь исключения использовались не для исключительных ситуаций  smile 

Автор: Lazin 24.12.2007, 08:54
Цитата(MAKCim @  22.12.2007,  10:43 Найти цитируемый пост)
я, честно говоря, не видел, чтобы где-нибудь исключения использовались не для исключительных ситуаций

я у страуса видел smile
имхо в большинстве случаев можно переписать код без гоуту и при этом в читабельность только вырастет... Хотя иногда без этого нельзя. У меня оператор goto появлялся только в очень больших функциях(неправильно спроектированных) smile.

Автор: bsa 24.12.2007, 12:38
Lazin, а у меня оператор goto появляется только там, где я это запроектировал. В частности, в функции с таблицей переходов (расширение gcc - позволяет преобразование void* к метке и обратно).

Автор: GrayCardinal 24.12.2007, 14:16
Народ, имейте совесть, что значит "нельзя использовать" оператор, который есть по стандарту в языке ? Не хочешь - не используй. Всё.

Автор: Albanec 30.12.2007, 17:34
    По мне дак оператор готу ето как одна из возможностей реализовать свою идею, и я скажу противникакм данного оператора что не стоит брызгая слюной арать что применение данного оператора не есть хорошо и что его применение приведет всех в ад))) По моему ето бред, 
    После создания нескольких програм на ассемблере, я понимаю что кроме оператора goto нету ни одного оператора который бы его заменил(в смысле на низком уровне прогрммирования), так что все операторы похожи на goto(просто в машином языке(ассемблер)нету других операторов), приведите мне хоть один низкоуровневый оператор типа if()  я вам памятник поставлю)).
   И скажите мне зачем его вводят во всех языках программирования если он "НЕ НУЖЕН ИЛИ БЕЗ НЕГО МОЖНО ОБОЙТИСЬ"???? 
   А на сечёт читаемости кода, полностью согласен читается трудно, но после некоторого опыта программирования на ассемблере ето детские сказки))
   Вообщем моё мнеие такое если использовать данный оператор то только если: без него не обоитись, или он улутшит читаемость кода.
   Но не в коем случае нельзя ставить крест на даном операторе)) надо его использовать с умом)) 

Автор: SaDFromSpb 30.12.2007, 18:10
Цитата(Lazin @  24.12.2007,  08:54 Найти цитируемый пост)
я у страуса видел

??!! Хде? Ссылку в студию!

Автор: nerezus 30.12.2007, 19:02
Цитата

 И скажите мне зачем его вводят во всех языках программирования если он "НЕ НУЖЕН ИЛИ БЕЗ НЕГО МОЖНО ОБОЙТИСЬ"???? 
 Так поэтому его в куче языков и нету ;)

Цитата

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

P.S. иног да бывает нужен. например при кодировании математического алгоритма, где описание основано на шагах с очень сложной связью.

Автор: Mayk 1.1.2008, 09:38
Цитата(Albanec @  30.12.2007,  21:34 Найти цитируемый пост)

   И скажите мне зачем его вводят во всех языках программирования если он "НЕ НУЖЕН ИЛИ БЕЗ НЕГО МОЖНО ОБОЙТИСЬ"???? 

В яве реализован выход из вложенных циклов. goto там уже нет. не помню чтоб кому то из за этого приходилось страдать.
Цитата(nerezus @  30.12.2007,  23:02 Найти цитируемый пост)

P.S. иног да бывает нужен. например при кодировании математического алгоритма, где описание основано на шагах с очень сложной связью. 

 smile 

Автор: MAKCim 1.1.2008, 10:53
Mayk
логика, которую можно описать табличными переходами внутри функции
Код

static void __calculate() {
    void * table[N] = {
        &&label1, &&label2, ..., &&labelN
    };
    
label1:
...
label2:
...
labelN:
...
}

компилятор GCC

Автор: nerezus 1.1.2008, 19:31
Цитата

 smile 
 тот же самый алгоритм многомерного поиска минимума Хука-Дживса. Там есть перекрестные шаги, а алгоритм пошаговый. В целях отладни лучше юзать прогу, где 1 шаг алгоритма - 1 блок рограммы.

Автор: SaDFromSpb 22.1.2008, 14:08
Цитата(nerezus @  1.1.2008,  19:31 Найти цитируемый пост)
тот же самый алгоритм многомерного поиска минимума Хука-Дживса. Там есть перекрестные шаги, а алгоритм пошаговый. В целях отладни лучше юзать прогу, где 1 шаг алгоритма - 1 блок рограммы. 

Хы хы. У нас реализован алгоритм Хука-Дживса. Гоуту не используется. Хотя я еще уточню у автора, когда он подойдет.

Автор: nerezus 22.1.2008, 14:12
У меня он тоже без goto.
Просто читаемость ухудшается )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)