LINUX.ORG.RU

Стиль switch - case

 ,


0

3

Увидел в http://www.linux.org.ru/forum/development/10302494 такой стиль:

    switch (event.type) {
        case SDL_QUIT: {
	    quit = 1;
        } break;
    }
Вопрос ко всем и к Bizun в частности.

В чем физический смысл такого «{...} break;»?

Я в этом вижу только яростную ненависть к goto. Господа, кто еще в мире пишет в таком стиле?

В каких open source проектах используют такой стиль программирования?

★★

Последнее исправление: fopen (всего исправлений: 1)
Ответ на: комментарий от Deleted

Если руками писать, то компилятор создаст нечто подобное (используются GCC'шные labels as values):

unsigned int x;

//в исходном коде, который компилируем значения в case были такие, что:
// V2 == V1+2; V3 == V2+1; V4 == V3+1; 
const unsigned int  V1 = .. значение V1 из исходного кода ..;


static void* jump_table = { &&l_V1, &&switch_end ,&&l_V2, &&l_V3, &&l_V4 };

if (x < V1) goto switch_end;

goto jump_table[x-V1];
l_V1: ...код в case V1....
l_V2: ....
l_V3: ....
l_V4: ....

switc_end: ... код после switch ... 

redbaron ★★
()
Последнее исправление: redbaron (всего исправлений: 2)
Ответ на: комментарий от redbaron

Да, суть уловил. Только в этих местах надо goto понатыкать:

l_V1: ...код в case V1.... goto switch_end
l_V2: ....goto switch_end
l_V3: ....goto switch_end
l_V4: ....
switch_end:
Иначе оно будет эквивалентно:
switch (0) {
    case 0:
    case 1:
    case 2:
    case 3:
}
Хотя, тебе это и так понятно, но пусть будет, может кто то разобраться захочет.

Deleted
()
Последнее исправление: Bizun (всего исправлений: 1)

Тред не читай @ сразу отвечай.

В чем физический смысл такого «{...} break;»?

Ограничение лексического блока видимости. case не порождает своего лексического scope, следовательно для обеспечения локальности лексических переменных нужно явно объявлять блок {}.

Sectoid ★★★★★
()

В чем физический смысл такого «{...} break;»?

Я в этом вижу только яростную ненависть к goto. Господа, кто еще в мире пишет в таком стиле?

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

Если разберешься к компиляторами, может всякие оптимизации к Clang напишешь :) Там хотябы понять что происходит можно, в отличии от GCC.

У меня была одна хотелка на этот счет, но не осилил :)

redbaron ★★
()

Я в этом вижу только яростную ненависть к goto.

А я вижу в этом namespace с блекджеком и эльфийками.

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

И вообще, goto надо использовать, когда он нужен!

т.е. никогда?
//относительно высокого уровня абстракций, понятно что без JMP никуда.

comp00 ★★★★
()
Последнее исправление: comp00 (всего исправлений: 1)
Ответ на: комментарий от comp00

т.е. никогда?

Ну отчего же так категорично?

Разумное использование goto в необходимых случаях вреда не приносит. Более того, было время, когда я в апплах на заказ пользовал чисто nix-овые костыли setjmp/longjmp (очень надо было), потом сопровождением этих прог занимался по нескольку лет, и ничего — код читался и «вспоминался» нормально, логика не корёжилась. Главное — не злупотреблять.

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

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

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

т.е. никогда?

Т.е. всегда, когда нужен. А это бывает часто. Минимальный пример — вложенные циклы. Еще пример — выход из функции (аналог try..catch).

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

Минимальный пример — вложенные циклы.

throw слишком модно?

Еще пример — выход из функции

что? Чем return не православен? Принудительный переход из/в подпрограмм[ы/e] через goto это уже выстрел не в ногу, а в голову, не иначе.

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

throw слишком модно?

man throw
Нет справочной страницы для throw

это есть в сях?

Чем return не православен?

А деструктор? У меня в куде вообще везде используется goto в функциях, чтобы вызывать разные деструкторы в случае ошибки. Иначе можно засрать видеопамять и будет жоппа.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от DeVliegendeHollander

А чего ты о сях в прошлом времени? Уже не пользуешься? Или там какие-то новые фичи появились?

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

Кстати, а давно ли по goto разрешают выходить за пределы тела функции?

Когда лепил апплы, не разрешалось, и именно поэтому приходилось задействовать костыли setjmp/longjmp. А как сейчас? (я на С давно ничего крупного не писал)

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

Уже не пользуешься?

Для больших заказных прожектов — нет. Только в личных целях. А личные задачки у меня не слишком сложные — в них goto нужен раз в 25 лет :-)

Или там какие-то новые фичи появились?

Да вроде как нет. Стандарт уже давно устаканился, а «нестандарта» я стараюсь избегать.

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

Кстати, а давно ли по goto разрешают выходить за пределы тела функции?

А я про это и не говорил. У меня просто в конце функции что-то вроде

destr1:
  free(a); free(b);
destr2:
  free(c); free(d);
  return ret;

естественно, меток может быть и больше. Ну, а вместо try() у меня свой макрос, который в случае ошибки делает goto на нужную метку.

По поводу longjmp: с этим делом я не связываюсь.

А личные задачки у меня не слишком сложные — в них goto нужен раз в 25 лет :-)

Ну, а у меня считай что все — личные задачки.

Для больших заказных прожектов — нет. Только в личных целях. А личные задачки у меня не слишком сложные — в них goto нужен раз в 25 лет :-)
«нестандарта» я стараюсь избегать

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

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

В сях исключений нет, не тот уровней абстракций. А вот в с++ уже есть. Зато в сях флаги никто не отменял. Почему бы не выходить по флагам?
Разные деструкторы??? Ума не приложу как и зачем, но тем же switch-ем можно добиться выполнение разных участков кода по условию.

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

Ну смотря где. В приложении на qt рчень даже можно. При программировании какой нибудь железки, действительно, лучше воспользоваться теми же флагами

comp00 ★★★★
()

Так необходимо делать если тебе в case надо переменную объявить. В остальном дело вкуса.

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

Скобочки обозначают логическую структуру, но тем самым вводят в заблуждение, т. к. это расходится с логикой switch.

Хм, интересное мнение. Но как по мне - вся суть switch'a выбрать некоторое действие исходня из одного значения. Как это нарушает логику конструкции?

Визуально. Такой стиль создает иллюзию структуры, в то время как структуры в switch нет.

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

Ну и на кой черт мне ваять жуткие конструкции со свитчами, если с метками и goto получается намного элегантней?

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

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

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

А чем тебе не симпатична функция free_all которая освобождает выделенную память, и вы ызывается в нужных тебе местах? Код читабельнее стал бы.

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

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

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

Если разберешься к компиляторами, может всякие оптимизации к Clang напишешь :) Там хотябы понять что происходит можно, в отличии от GCC.

Не, там проекты большие и сложные, пусть их больлшие дядьки пишут :)

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

В сях исключений нет, не тот уровней абстракций. А вот в с++ уже есть. Зато в сях флаги никто не отменял. Почему бы не выходить по флагам?

Пример что ли кинь.

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