LINUX.ORG.RU

Re: Почему советуют избегать JMP?

Потому что ломает code flow программы, так-же как и множественные return-ы, и код становится менее плаитичным.

fmjs ()

Re: Почему советуют избегать JMP?

За исходными причинами - google for "Goto considered harmful". Типо, вместе с другими мероприятиями, увеличивает модульность кусков кода.

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

Посмотри в исходники ядра - goto для обработки ошибок только так используется.

gods-little-toy ★★★ ()

Re: Почему советуют избегать JMP?

У Кнута есть неплохая статья, в которой он показывает, что goto в алголоподобных языках в той или иной форме необходим.

Miguel ★★★★★ ()

Re: Почему советуют избегать JMP?

Отлаживать программы с многочисленными goto - проще пристрелить того, кто их писал ;-).

В _редких_ случаях вариант с goto будет лучше, чем без него. Обычно указывают необходимость выхода из множества вложенных в друг друга циклов в сложных алгоритмах.

record ★★★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от record

Re: Почему советуют избегать JMP?

> Обычно указывают необходимость выхода из множества вложенных в друг друга циклов в сложных алгоритмах.
А если речь идёт об условиях в циклической программе (речь в данном случае конкретно про jmp, goto я привёл для сравнения)
Т.е. эффективен ли джамп в таком коде:
if (..) {goto a}
if (..) {}
if (..) {}

// общий код
a: ..

в данном случае время обработки программы в rt-системе. сократится, т.к. второй и третий if обрабатываться не будут.

UVV ★★★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от UVV

Re: Почему советуют избегать JMP?

>эффективен ли джамп

переход-то эффективен. Более того, использование goto может до предела оптимизировать алгоритм, только, что толку: через неделю, никто, включая автора, не сможет объяснить, как это все работает. И включить в программу доп. фичу становится очень проблематично. Если, конечно, это не учебный пример в одну страничку.

record ★★★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от UVV

Re: Почему советуют избегать JMP?

было: (я ввел некие названия, для улучшения читабельности)

if (cond1) {goto a} 
if (cond2) {} 
if (cond3) {} 

// общий код 
do_something_before_lable();
a:
do_something_after_lable();

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

if (!cond1) 
{
    if (cond2) {} 
    if (cond3) {} 
    // общий код 
    do_something_before_lable();
}
a:
do_something_after_lable();

fmjs ()
Ответ на: Re: Почему советуют избегать JMP? от UVV

Re: Почему советуют избегать JMP?

> в данном случае время обработки программы в rt-системе. сократится, т.к. второй и третий if обрабатываться не будут.

А за использование goto в RT системах стоит увольнять.

fmjs ()

Re: Почему советуют избегать JMP?

Я тоже воспользовался goto. Точный код я сейчас не помню, но смысл покажу:


if ((...)==-1) goto err; // -1 возвращается при ошибке
if ((...)==-1) goto err; // -1 возвращается при ошибке
if ((...)==-1) goto err; // -1 возвращается при ошибке
....
exit(0);

err:
... // тыр-пыр-8-дыр...
exit(1);

Можно ли писать так?

hibou ★★★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от UVV

Re: Почему советуют избегать JMP?

Насколько я вспомнил, там создание сокета на стороне сервера было... множественное соединение не требовалось. Т.е. сервер и 1-н клиент.

hibou ★★★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от fmjs

Re: Почему советуют избегать JMP?

> При включенном оптимизаторе, что-нибудь вроде -Os -- запросто.
Речь не о gcc и тем более не об i386.
Есть процессор и свой компилятор к нему.
Поэтому я речь веду с алгоритмической точки зрения.

UVV ★★★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от UVV

Re: Почему советуют избегать JMP?

> Но на вложенный if уйдёт намного больше времени.

Вуаля:

1.c: 

#include <stdio.h>

int main()
{
        if (getc(stdin) == '0')
        {
                if (getc(stdin) == '1')
                        printf("first\n");
                if (getc(stdin) == '2')
                        printf("2nd\n");

                printf("do something before lable\n");
        }

        printf("do something after lable\n");

        return 0;
}

2.c:

#include <stdio.h>

int main()
{
        if (getc(stdin) != '0')
                goto a;
        if (getc(stdin) == '1') 
                printf("first\n");
        if (getc(stdin) == '2') 
                printf("2nd\n");

        printf("do something before lable\n");
a:      
        printf("do something after lable\n");
        
        return 0;
} 


Билдым: 

$ make CFLAGS=-Os 1
$ make CFLAGS=-Os 2

стрипаем:

$ strip 1 2

смотрим:

$ diff -u 1 2
$ ls -l 1 2 
-rwxr-xr-x   1 fmjs     fmjs     13668 Jul 13 13:55 1
-rwxr-xr-x   1 fmjs     fmjs     13668 Jul 13 13:55 2

$ gcc --version
powerpc-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5250)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



Итого, если в бинарном коде нет разницы, то откуда возмется "Но на вложенный if уйдёт намного больше времени."

fmjs ()
Ответ на: Re: Почему советуют избегать JMP? от UVV

Re: Почему советуют избегать JMP?

> Есть процессор и свой компилятор к нему.

Подобного рода оптимизацию умеют производить 99% процентов компиляторов.

fmjs ()
Ответ на: Re: Почему советуют избегать JMP? от fmjs

Re: Почему советуют избегать JMP?

> Подобного рода оптимизацию умеют производить 99% процентов компиляторов.

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

fmjs ()
Ответ на: Re: Почему советуют избегать JMP? от UVV

Re: Почему советуют избегать JMP?

Ээээ.

А кто тебе сказал, что в _генерируемом_ коде jmp чем-то плох? Куда ж без него-то?

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

anonymous ()

Re: Почему советуют избегать JMP?

Религии зло. Религия "не используйте goto" тоже зло.

Просто ко всему нужно подходить с головой. Штатные конструкции if/switch/while/do удобнее читать и анализировать, чем аналогичный код с goto.

Если можно обойтись штатными конструкциями (как тут выше было с if) и при этом не потерять читабельность и производительность, то лучше пользоваться ими. Если нельзя, то можно воспользоваться goto.

execve ()
Ответ на: Re: Почему советуют избегать JMP? от fmjs

Re: Почему советуют избегать JMP?

А я немного изменю: if (cond1) { rv = -1; goto err; } if (cond2) { rv = -1; goto err; } if (cond3) { rv = -1; goto err; } ... if (condn) { rv = -1; goto err; }

do_ok();

err: cleanup(); if (rv) { .... } else { .... }

Теперь без goto. if (!cond1) { if (!cond2) { if (!cond3) { .... if (!condn) { } .... } } }

Отступы нереальные.

P.S. кроме того: #define ASSERT(some) \ do { \ if (!(some)) { \ rv = -1; \ goto err; \ } } while (0)

и: ASSERT(cond1); ASSERT(cond2); ...

P.P.S. Сам goto не использую почти никогда :)

rymis ★★ ()
Ответ на: Re: Почему советуют избегать JMP? от fmjs

Re: Почему советуют избегать JMP?

А я немного изменю:
if (cond1) { rv = -1; goto err; }
if (cond2) { rv = -1; goto err; }
if (cond3) { rv = -1; goto err; }
...
if (condn) { rv = -1; goto err; }

do_ok();

err:
     cleanup();
     if (rv) {
         ....
     } else {
         ....
     }

Теперь без goto.
if (!cond1) {
    if (!cond2) {
         if (!cond3) {
              ....
                                            if (!condn) {
                                            }
              ....
         }
    }
}

Отступы нереальные.

P.S. кроме того:
#define ASSERT(some) \
    do { \
        if (!(some)) { \
             rv = -1; \
             goto err; \
        }
    } while (0)

и:
ASSERT(cond1);
ASSERT(cond2);
...

P.P.S. Сам goto не использую почти никогда :)

rymis ★★ ()
Ответ на: Re: Почему советуют избегать JMP? от rymis

Re: Почему советуют избегать JMP?

> Теперь без goto. if (!cond1) { if (!cond2) { if (!cond3) { .... if (!condn) { } .... } } }

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

В подобных случаях, код рекомендуется разбивать на более мелкие логические блоки, а если это сложно выполнимо, ввиду того что "это особый случай", то тогда да, это особый случай, юзайте хоть goto, хоть longjump

fmjs ()
Ответ на: Re: Почему советуют избегать JMP? от rymis

Re: Почему советуют избегать JMP?

> Теперь без goto.
> if (!cond1) {
>     if (!cond2) {
>          if (!cond3) {
>               ....
>                                             if (!condn) {
>                                             }
>               ....
>          }
>     }
> }

или

bool isOk = true;

if (isOk && !cond1) { rv = -1; isOk = false; }
if (isOk && !cond2) { rv = -1; isOk = false; }
if (isOk && !cond3) { rv = -1; isOk = false; }
if (isOk && !cond4) { rv = -1; isOk = false; }
if (isOk && !cond5) { rv = -1; isOk = false; }
if (isOk && !cond6) { rv = -1; isOk = false; }
if (isOk && !cond7) { rv = -1; isOk = false; }

if (isOk)
{
    do_ok();
}

fmjs ()
Ответ на: Re: Почему советуют избегать JMP? от fmjs

Re: Почему советуют избегать JMP?

Абсолютно согласен, но такой вариант требует проверки (n-1) условия, а goto отвалится сразу.

А на тему отрывания различных частей тела:
struct info {
     part1_t * part1;
     part2_t * part2;
...
     partn_t * partn;
};

struct info * info_new(...)
{
     struct info * result;
     int res;

     result = malloc(...);
     result->part1 = part1_t_new();
     if (!result->part1) { res = -1; goto err; }
     ....
     result->partn = partn_t_new();
     if (!result->partn) { res = -1; goto err; }

     return result;
err:
     if (result->part1)
          part1_t_destroy(result->part1);
....
     free(result);
     return NULL;
}

Классическая ситуация создания объекта (например в GTK). Экзотика?

rymis ★★ ()
Ответ на: Re: Почему советуют избегать JMP? от rymis

Re: Почему советуют избегать JMP?

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

На (ужасном, ужасном) Си-крест-крест такое решается созданием объектов на стеке внутри одного большого try-блока.

anonymous ()
Ответ на: Re: Почему советуют избегать JMP? от anonymous

Re: Почему советуют избегать JMP?

Конечно. Я и не отрицаю, что на чистом Си бывает сложно писать, но это не говорит о том, что проектов на нем нет. Я против использования goto, но сказать, что использовать его нельзя, было бы неправильно.

А в быдло(Выберите язык со сборщиком мусора) вообще не возникло бы таких проблем :)

rymis ★★ ()
Ответ на: Re: Почему советуют избегать JMP? от rymis

Re: Почему советуют избегать JMP?

> А в быдло(Выберите язык со сборщиком мусора)

Например Быдло-лисп ?

> вообще не возникло бы таких проблем :)

в лиспе вроде goto есть... желающие - могут проблемы иметь :-)

gods-little-toy ★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от rymis

Re: Почему советуют избегать JMP?

Как раз наоборот. Сборщики мусора пока что умеют собирать только память. А идиома "занятие ресурса == создание объекта на стеке" подразумевает вызов деструктора в предопределенное время.

Такое работает только при явном управлении памятью (или какой-то смешанной модели, типа "стековые удаляются при разрушении контекста, хиповые - гарбаж-коллектором" (кажется, в D так можно) или в случае рефренс-каунтинга, как в перле - но в перле порядок деструкции не определен).

anonymous ()

Re: Почему советуют избегать JMP?

Дело привычки и задач.

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

Вообще goto не просто нельзя использовать, его нужно использовать! Но надо понимать когда стоит его использовать. Вот и все.

catap ★★★★★ ()
Ответ на: Re: Почему советуют избегать JMP? от catap

Re: Почему советуют избегать JMP?

> Когда ты пишешь что-то очень-очень-очень низко, то goto твой верный друг, ибо позволяет, при грамотном использование, избежать дублирования кода (когда функциями оборачивать тяжелее).

Только большая часть здещних обитателей говорящих о том, что goto полезен на low-level-е, никогда на этот low-level и не спускались :)

fmjs ()
Ответ на: Re: Почему советуют избегать JMP? от fmjs

Re: Почему советуют избегать JMP?

> Только большая часть здещних обитателей говорящих о том, что goto полезен на low-level-е, никогда на этот low-level и не спускались :)
Ну вот я поэтому тему и создал, что сейчас я на этом уровне! ;-)

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