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. Нужно ли избавиться от нее и если да то как это лучше сделать?
★★★★

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

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

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

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

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

dd в виме.

bugmaker ★★★★☆
()

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

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

Значит надо оставить все как есть, спасибо за быстрый ответ.

ViTeX ★★★★
() автор топика

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

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

Die-Hard ★★★★★
()
Ответ на: комментарий от bugmaker

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

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

php-coder ★★★★★
()
Ответ на: комментарий от Die-Hard

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

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

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

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

       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 ★★★★☆
()

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

shumer
()
Ответ на: комментарий от Die-Hard

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

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

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

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

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

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

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

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

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

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

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

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

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

guardian
()

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

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

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

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

Да и вообще на любом языке, эквиваленьтном иашине Тьюринга модно всё написать:) Например есть brainfuck. Только нужно ли...

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

brainfuck говоришь... (-_-)

Есть ли смысл radio через дефаин определить для красоты кода?

ViTeX ★★★★
() автор топика

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

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

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

dilmah ★★★★★
()
Ответ на: комментарий от Die-Hard

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

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

2dilmah:

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

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

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

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

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

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

bbk123 ★★★★★
()

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

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

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

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

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

php-coder ★★★★★
()
Ответ на: комментарий от Onanim

Из-за обилия Ж - жопный код получается:)

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

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

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

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

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

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

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

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

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