LINUX.ORG.RU
ФорумTalks

кто тут не любит goto?


0

2

Зачастую оператор goto поможет сильно упростить жизнь или же вообще является единственной вменяемой возможностью.

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

★★★★★
Ответ на: комментарий от AptGet

С какой версии стандарта?

Не знаю, просто код с такой штукой видел пару раз.

Sadler ★★★
()
Ответ на: комментарий от cvs-255

Флаги это безусловно костыль. Тут не с чем спорить. Флаги вызывали у меня зубную боль ещё в десятом классе, инстинктивно. Но в pascal (на котором я писал тогда) и в C (о котором мы говорим сейчас) нет нормального loop managment. И нет try...catch, которые появились в C++, и которые тоже очень помогают жить.

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

Назови хотя бы 1 недостаток goto кроме запутанности кода. И то «запутанность кода» это субъективное мнение.

TDrive ★★★★★
()

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

JFreeM ★★★☆
()

Эдсгер Дейкстра, например. Расскажи ему кулстори про массивы переменной размерности, хороший вкус и вообще сперва добейся, ага?

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

Было время, в С++ их тоже не было :) И как-то жили... Ядра осей писали - никто не умер. А в соседнем треде внезапно аду плюсам предпочитают - видать, жизнь облегчить хотят... Doing it wrong во все поля.

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

Ядра осей писали

На Си, да, без надежды на внезапное облегчение жизни.

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

Добросовестно заблуждаясь в трех соснах можно придумывать «хитрые» решения для выхода :)

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

Попробуй FreeSans. А еще очень красивый FreeMono: линии тонкие и чёткие.

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от cvs-255

Куда то странным образом делась возможность нормального оформления

Тег code работает только в режиме TeX paragraphs.

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

try...catch

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

quantum-troll ★★★★★
()

Вам в Вашем радиотехническом колледже не рассказывали, что в нормальном языке программирования оператора goto не существует?

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

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

ещё выход из многократно вложенных друг в друга циклов, имхо.

Voviandr
()

Зачастую оператор goto поможет сильно упростить жизнь или же вообще является единственной вменяемой возможностью.

Пример, пожалуйста

Зачастую

Лолчто?

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

на фразе «обход цикла в массиве», я завис...
Да, а еще GOTO неистово путает программиста, особенно если он (и/или они) не одни.

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

Например обход в цикле массива

на фразе «обход цикла в массиве», я завис...

Глючить ты начал еще раньше.

tailgunner ★★★★★
()

Погрепал свой код, вот такие примеры,

static int
clip_line(point_t *s, point_t *e)
{
	int		s_cc = clip_code(s);
	int		e_cc = clip_code(e);
	float		lim_w = (float) (screen_w - 2);
	float		lim_h = (float) (screen_h - 2);
	float		dx, dy;

	do {
		if (s_cc & e_cc)
			return -1;

		if (!(s_cc | e_cc))
			return 0;

		if (!s_cc) {

			int tmp = s_cc;
			s_cc = e_cc;
			e_cc = tmp;

			point_t *ptmp = s;
			s = e;
			e = ptmp;
		}

		dx = e->x - s->x;
		dy = e->y - s->y;

		if ((fabsf(dx) < 1.0f) && (s_cc & 0x03))
			return -1;

		if ((fabsf(dy) < 1.0f) && (s_cc & 0x0c))
			return -1;

		if (s_cc & 0x01) {
			s->y = e->y + ((0.0f - e->x) * dy) / dx;
			s->x = 0.0f;
			goto __cl_recalc;
		}

		if (s_cc & 0x02) {
			s->y = s->y + ((lim_w - s->x) * dy) / dx;
			s->x = lim_w;
			goto __cl_recalc;
		}

		if (s_cc & 0x04) {
			s->x = e->x + ((0.0f - e->y) * dx) / dy;
			s->y = 0.0f;
			goto __cl_recalc;
		}

		if (s_cc & 0x08) {
			s->x = s->x + ((lim_h - s->y) * dx) / dy;
			s->y = lim_h;
			goto __cl_recalc;
		}

__cl_recalc:
		s_cc = clip_code(s);
	}
	while (1);
}
static void
in_module_link(struct parser *ps, struct lexer *lex, struct module *m)
{
	struct module	*l;
	struct link	*ln;
	struct port	*p;
	list_node_t	unils;
	link_node_t	*lk, *lkn;
	char		id[LEXER_SYM_MAX + 1];
	int		defval;
	int		fail;
	int		err = 0;

	list_up(&unils);
	defval = SIGNAL_INVALID;

	do {
		lexer_token_next(lex);

iml_do_token:

		if (lex->tok.id == TOKEN_SYMBOL) {

			strcpy(id, lex->tok.val);

			lexer_token_next(lex);

			if (lex->tok.id == TOKEN_DOT) {

				lexer_token_next(lex);

				if (lex->tok.id == TOKEN_SYMBOL) {

					fail = 1;

					list_for_each(&m->local, l) {
						if (strcmp(l->lid, id) == 0) {
							fail = 0;
							break;
						}
					}

					if (fail) {
						fprintf(stderr, "%s:%i: parser: undeclared local module \"%s\"\n",
								lex->fname, lex->line, id);
						ps->error++; err = 1; continue;
					}

					fail = 1;

					list_for_each(&l->port, p) {

						if (strcmp(p->id, lex->tok.val) == 0) {
							list_insert(&unils, link_node_alloc(p));
							fail = 0;
							break;
						}
					}

					if (fail) {
						fprintf(stderr, "%s:%i: parser: undeclared local module port \"%s\"\n",
								lex->fname, lex->line, lex->tok.val);
						ps->error++; err = 1; continue;
					}
				}
				else if (lex->tok.id == TOKEN_SEMICOLON) {
					fprintf(stderr, "%s:%i: parser: incomplete expression after dot keyword\n",
							lex->fname, lex->line);
					ps->error++; err = 1; break;
				}
				else {
					fprintf(stderr, "%s:%i: parser: port identifier of local module is expected"
							" after the dot\n",
							lex->fname, lex->line);
					ps->error++; err = 1; continue;
				}
			}
			else {
				fail = 1;

				list_for_each(&m->port, p) {

					if (strcmp(p->id, id) == 0) {
						list_insert(&unils, link_node_alloc(p));
						fail = 0;
						break;
					}
				}

				if (fail) {
					fprintf(stderr, "%s:%i: parser: undeclared local port \"%s\"\n",
							lex->fname, lex->line, id);
					ps->error++; err = 1; continue;
				}

				goto iml_do_token;
			}
		}
		else if (lex->tok.id == TOKEN_PLUS) {

			if (defval == SIGNAL_INVALID)
				defval = SIGNAL_PULL_UP;
			else {
				fprintf(stderr, "%s:%i: parser: plus sign overrides default value %d\n",
						lex->fname, lex->line, defval);
				ps->error++; err = 1;
			}
		}
		else if (lex->tok.id == TOKEN_MINUS) {

			if (defval == SIGNAL_INVALID)
				defval = SIGNAL_PULL_DOWN;
			else {
				fprintf(stderr, "%s:%i: parser: minus sign overrides default value %d\n",
						lex->fname, lex->line, defval);
				ps->error++; err = 1;
			}
		}
		else if (lex->tok.id == TOKEN_SEMICOLON)
			break;
		else {
			fprintf(stderr, "%s:%i: parser: identifier or semicolon or sign is expected\n",
					lex->fname, lex->line);
			ps->error++; err = 1; break;
		}
	}
	while (1);

	...
}

плохо?

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

«if you need more than 3 levels of identation, you're screwed anyway, and should fix your program» (c)

«Functions should be short and sweet [...] should fit in one or two screenfuls of text (the ISO/ANSI screen size is 80x24, as we all know)» (с)

плохо?

За goto назад следует убивать^Wнаказывать.

tailgunner ★★★★★
()

планировщик Торвальдса уже вспоминали? :)

на всякий случай (последний абзац):

/*
 *  'schedule()' is the scheduler function. It's a very simple and nice
 * scheduler: it's not perfect, but certainly works for most things.
 * The one thing you might take a look at is the signal-handler code here.
 *
 *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other
 * tasks can run. It can not be killed, and it cannot sleep. The 'state'
 * information in task[0] is never used.
 *
 * The "confuse_gcc" goto is used only to get better assembly code..
 * Dijkstra probably hates me.
 */

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

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

Вместо этого

		if (s_cc & 0x01) {
			s->y = e->y + ((0.0f - e->x) * dy) / dx;
			s->x = 0.0f;
			goto __cl_recalc;
		}

		if (s_cc & 0x02) {
			s->y = s->y + ((lim_w - s->x) * dy) / dx;
			s->x = lim_w;
			goto __cl_recalc;
		}

		if (s_cc & 0x04) {
			s->x = e->x + ((0.0f - e->y) * dx) / dy;
			s->y = 0.0f;
			goto __cl_recalc;
		}

		if (s_cc & 0x08) {
			s->x = s->x + ((lim_h - s->y) * dx) / dy;
			s->y = lim_h;
			goto __cl_recalc;
		}
лучше вот так:
if (s_cc)
  switch(flag) {
  0x01:
    s->y = e->y + ((0.0f - e->x) * dy) / dx;
    s->x = 0.0f;
    break;		

  0x02:
    s->y = s->y + ((lim_w - s->x) * dy) / dx;
    s->x = lim_w;
    break;

  0x04:
    s->x = e->x + ((0.0f - e->y) * dx) / dy;
    s->y = 0.0f;
    break;

  0x08:
    s->x = s->x + ((lim_h - s->y) * dx) / dy;
    s->y = lim_h;
    break;
  }

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

«if you need more than 3 levels of identation, you're screwed anyway, and should fix your program»

eps[a][c][d] - вполне частая конструкция, когда вы делаете что-то в четырехмерном пространстве

cvs-255 ★★★★★
() автор топика
Ответ на: комментарий от cvs-255

more than 3 levels of identation

eps[a][c][d]

Кхм. ЛОЛШТО? Даже если предположить, что ты перепутал indentation и indirection, где у тебя больше 3-х уровней?

tailgunner ★★★★★
()
Ответ на: комментарий от cvs-255

Тогда вернемся к вопросам, не перепутал ли ты indentation с indirection, и какое отношение ранг тензора имеет к правилам оформления программного кода.

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

Вам в Вашем радиотехническом колледже не рассказывали, что в нормальном языке программирования оператора goto не существует?

Если в язык программирования добавить goto это его испортит? Вам goto что по ночам в кошмарах снится? Откуда такая паранойя?

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

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

TDrive ★★★★★
()
Ответ на: комментарий от cvs-255

А, вот ты о чем... значит, программы для обработки тензоров с большим рангом формально не вписываются в рамки Linux coding style.

tailgunner ★★★★★
()

кто тут не любит goto?

Я не люблю нечитабельный код. С goto или без него, это не важно.

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

В чистом Си без goto никуда

Пример в студию. По-моему, все можно написать без применения goto. Да, иногда он может быть полезен. Но редко. Я его еще ни разу не применял.

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

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

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

Канонические примеры найдешь в исходниках ядра.

Лень грепать:)

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

Нагромождение.

См. drivers/net/sb1000.c:sb1000_probe_one (не то, чтобы мне нравился именно такой стиль, но он иллюстрирует идею).

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

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

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

потом туда еще придется передавать 100500 параметров

Да, об этом не подумал.

HerrWeigel ★★★★
()

кстати, ненавно столкнулся с одно стат. либой (cdflib). она, правда, изначально была написана на фортране и, похоже, какой-то тулзой сконвертирована в си, но goto-хейтерам должно понравиться: (беременным, детям и программистам смотреть не рекомендуется) http://www.koders.com/c/fidA036FBCAED1BDAF08246DD6C3CCE7D9B29170540.aspx?s="d... :)

arsi ★★★★★
()

Вот оператор goto:

for(;;) {
  if (cond1) break;
  Do();
  if (cond2) break;
  Do3();
  break;
}
queen3 ★★★★★
()

Уж сколько раз твердили миру - для массивов нужно использовать итераторы а не циклы

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

О, отличная вещь, спасибо. Обязательно посмотрю завтра

HerrWeigel ★★★★
()

В исходниках gforth можно посмотреть на православное использование вычисляемого goto.

buddhist ★★★★★
()

В C/C++, PHP, JS без goto можно обойтись в 100% случаях, при сохранении хорошей (даже лучшей по срвнению с использованием goto) читабельности кода. Pascal - уже не помню. Basic - в зависимости от разновидности, на VB, по-моему тоже можно без goto, но не уверен. ASM - как я помню goto действительно очень выручает. Bash - тоже пока goto нигде не использовал.

Тред проскипал. В примерах, на которые смотрел, goto только запутывает (особенно там, где он прыгает в середину цикла - жуть!).

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

ASM - как я помню goto действительно очень выручает

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

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