LINUX.ORG.RU

Вопрос про использование GOTO


0

0

В модуле ядра для включения вайфай имеется следующая процедура:

static int amiloa1655g_proc_init(void)
{
	struct proc_dir_entry *ent;
	int err = 0;

	dir_base = create_proc_entry(DRV_NAME, S_IFDIR, &proc_root);
	if (dir_base == NULL) {
		printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" 
		       DRV_NAME "\n");
		err = -ENOMEM;
		goto fail;
	}


	ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR, 
				dir_base);
	if (ent) {
		ent->read_proc = proc_get_radio;
		ent->write_proc = proc_set_radio;
	} else {
		printk(KERN_ERR
		       "Unable to initialize /proc/" DRV_NAME "/radio\n");
		err = -ENOMEM;
		goto fail;
	}

	return 0;

 fail:
	amiloa1655g_proc_cleanup();
	return err;
}

Модуль работает отлично, однако смущает наличие конструкции goto. Нужно ли избавиться от нее и если да то как это лучше сделать?
★★★★

Re: Вопрос про использование GOTO

> однако смущает наличие конструкции goto

Исходники фряхи полистай, там этих готов вообще тьма.

> Нужно ли избавиться от нее

как хочеш, если считаеш, что более квалифицирован чем разработчик этого - вперёд.

> как это лучше сделать?

dd в виме.

bugmaker ★★★★☆ ()

Re: Вопрос про использование GOTO

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

anonymous ()

Re: Вопрос про использование GOTO

Однако, кто-то из классиков структурного программирования показал пару примеров, когда goto неизбежен...

Одно надо помнить -- в суперскалярных процессорах goto херит все конвейеры... Но компиятор обычно это дело способен соптимизировать ;)

Die-Hard ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от bugmaker

Re: Вопрос про использование GOTO

>Исходники фряхи полистай, там этих готов вообще тьма.

Хотел сказать почти тоже самое, только не про Фряху, а про OpenBSD. Я так понимаю это не то что нормально, а даже правильно...

php-coder ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от Die-Hard

Re: Вопрос про использование GOTO

>Однако, кто-то из классиков структурного программирования показал пару примеров, когда goto неизбежен...

Так, если не ошибаюсь, говорилось про вложенные циклы ? А здесь в принципе можно вполне и без goto обойтись..

php-coder ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от php-coder

Re: Вопрос про использование GOTO

Считается что так оптимальнее в некоторых случяях. 
Но лично мне готы не нравятся. Хотя мож от таково кода тож ктото проблюёцо:

       if (                                                                                                     
                (                                                                                                
                        (NULL == (dpy = getenv ("DISPLAY"))) &&                                                  
                        (fprintf (stderr, "DISPLAY variable is not set\n"))                                      
                ) || (                                                                                           
                        (NULL == (pwd = getpwuid (geteuid ()))) &&                                               
                        -1                                                                                       
                ) || (                                                                                           
                        snprintf (dstdir, UNIX_PATH_MAX, "%s/%s%s-%s", tmpdir, COMM_DIR, dpy, pwd->pw_name),     
                        (                                                                                        
                                (-1 == stat (dstdir, &fs)) &&                                                    
                                (                                                                                
                                        (i = d_stat1, ENOENT != errno) ||                                        
                                        (i = d_create, -1 == mkdir (dstdir, S_IFDIR | S_IRWXU)) ||               
                                        (i = d_stat2, -1 == stat (dstdir, &fs))                                  
                                )                                                                                
                        ) || (                                                                                   
                                (i = get_uid, geteuid () != fs.st_uid) &&                                        
                                (i = get_gid, getegid () != fs.st_gid)                                           
                        ) || (                                                                                   
                                (i = d_isdir, S_IFDIR != (S_IFDIR & fs.st_mode)) ||                              
                                (                                                                                
                                        (S_IRWXU != (0777 & fs.st_mode)) &&                                      
                                        (i = d_mode, -1 == chmod (COMM_DIR, S_IRWXU))                            
                                )                                                                                
                        )                                                                                        
                ) ||                                                                                             
                snprintf (sa.sun_path, UNIX_PATH_MAX, "%s/%s", dstdir, COMM_SOC),                                
                DEBUG_MSG (printf ("sock is %s\n", sa.sun_path)),                                                
                (-1 == (i = d_sock, s = socket (PF_UNIX, SOCK_STREAM, 0))) ||                                    
                (connect (s, (struct sockaddr *) &sa, sizeof (sa)), ((ECONNREFUSED != errno) && ((errno = EADDRIN
                (unlink (sa.sun_path),-1 == (i = d_bind, bind (s, (struct sockaddr *) &sa, sizeof (sa)))) ||     
                (-1 == (i = d_listen, listen (s, 1))) ||                                                         
                0                                                                                                
        ) {                                                                                                      
                perror ("error");                                                                                
                close (s);                                                                                       
                s = -1;                                                                                          
        }                                                                                                        
        return s;                      

bugmaker ★★★★☆ ()

Re: Вопрос про использование GOTO

Да переделать-то несложно. Две строчки под меткой fail поставить вместо goto в оба if. Только надо ли? Будет у функции три точки выхода размазанных по всему телу, вместо двух рядом в конце. По-моему это хуже чем использование goto.

shumer ()
Ответ на: Re: Вопрос про использование GOTO от Die-Hard

Re: Вопрос про использование GOTO

> Однако, кто-то из классиков структурного программирования показал пару примеров, когда goto неизбежен...

Математически доказано, что имея if и while можно обойтись без гота. Учим матчасть ;)

Kpoxman ★★ ()
Ответ на: Re: Вопрос про использование GOTO от Kpoxman

Re: Вопрос про использование GOTO

> Математически доказано, что имея if и while можно обойтись без гота. Учим матчасть ;)

Ага, и вообще всё можно написать на ассемблере.

vasirck ()
Ответ на: Re: Вопрос про использование GOTO от Kpoxman

Re: Вопрос про использование GOTO

>Математически доказано, что имея if и while можно обойтись без гота. Учим матчасть ;)

Математически доказано, что if тоже не нужен

ival ★★ ()
Ответ на: Re: Вопрос про использование GOTO от Kpoxman

Re: Вопрос про использование GOTO

>Математически доказано, что имея if и while можно обойтись без гота. Учим матчасть ;)

ровно как имея if и goto можно обойтись без while например, это как посмотреть :)

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

И код выглядит более читаемо, чем с кучей if.

guardian ()

Re: Вопрос про использование GOTO

вот что лично меня смущает, так это использование "забитых" в код значений, вроде 

ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR,dir_bas);
                        ^^^^^^^

дефайны и то приемлимее.   

guardian ()

Re: Вопрос про использование GOTO

типичные ненавистники гото -- зомбированное быдло

В локальном гото внутри небольшой функции нет ничего плохого

Плохо -- нелокальное гото типа setjmp/longjmp. Или гото внутри простыни на N тысяч строк

dilmah ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от Die-Hard

Re: Вопрос про использование GOTO

Можно подробнее про х*рение конвеера при гото? Я думал что конвеер может х*риться при условном бранче, а не при безусловном. Безусловный максимум дополнительную нагрузку на kэш создает?

dilmah ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от dilmah

Re: Вопрос про использование GOTO

2dilmah:

> Я думал что конвеер может х*риться при условном бранче, а не при безусловном.

Я не специалист в этом вопросе, просто озвучил многократно прочитанное.

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

Die-Hard ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от Die-Hard

Re: Вопрос про использование GOTO

> Одно надо помнить -- в суперскалярных процессорах goto херит все конвейеры...

По моему Вы путаете с предсказанием ветвлений, которое на условных переходах не всегда работает как надо. goto это просто jmp, который совершенно не влияет на это.

bbk123 ★★★★★ ()

Re: Вопрос про использование GOTO

просто ремарка по памяти :

goto вреден при машинно-независимой оптимизации программы, то есть программа использующая только уловные циклы и ветвления без goto,setjmp и exception лучше поддаётся автоматизированной оптимизации по быстродействию или объёму памяти. Где-то лет д`цать назад была очень модна такая вещь как теория схем программ,которая как-раз и была посвещенна оптимизации и распараллеливанию. Один из выводов теории: Длинный или непредсказуемый goto херит наглухо любой метод.

MKuznetsov ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от bugmaker

Re: Вопрос про использование GOTO

>Хотя мож от таково кода тож ктото проблюёцо:

Мдаааа... хорошо, что мне не приходится имет дело с твоим кодом ;-) А то из-за обилия скобок он на Лисп походит)))

php-coder ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от MKuznetsov

Re: Вопрос про использование GOTO

goto не может быть непредсказуемым. При правильном использовании goto может сам по себе являться элементом оптимизации. Попробуй переписать amiloa1655g_proc_init() без goto сравни как его оптимизирует компилятор.

bbk123 ★★★★★ ()
Ответ на: Re: Вопрос про использование GOTO от bbk123

Re: Вопрос про использование GOTO

bbk123(*) (04.06.2006 13:01:36):

> По моему Вы путаете с предсказанием ветвлений, которое на условных переходах не всегда работает как надо.

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

> goto это просто jmp, который совершенно не влияет на это.

Насколько я помню, проблемы были именно с бессистемными jmp в котексте условных переходов.

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