|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:19 am
Използване на goto и labels в C
| Автор |
Съобщение |
|
tgi
Ранг: Форумен бог
Регистриран на: Нед Юни 10, 2007 2:22 pm Мнения: 6492 Местоположение: София
|
То в тоя ред на мисли гърчът да се навре написването на роман във фразите предлагани
в разговорника - избягвайки една заклеймена като лоша - е истински "смахнатото".
_________________------------------- www.tgi-sci.com------------------- http://www.flickr.com/photos/didi_tgi/
|
| Пон Сеп 20, 2010 5:44 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
Ако мислиш, че ще направиш кода си по-четим използвай 'goto' няма проблем! Но имай предвид, че това е много субективно. Нещо дето е четимо за теб, може да е много нечетимо за други. Като се има предвид, че много С/С++ програмисти ненавиждат 'goto' то познай колко четим ще е твоя код за другите
Що се отнася до другите твърдения, повярвай ми *НЯМА* нищо вярно в тях, поне не и за съвременните компилатори. А ако не ми вярваш, да ми код с 'goto', аз ще го пренапиша без гото и ще сравним листингите...
|
| Пон Сеп 20, 2010 6:05 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
И тъй като не обичам да приказвам празни приказки взех примера на @radolin:
ето и резултата:  |  |  |  | Код: 00015b18 <goto_test()>: 15b18: b500 push {lr} 15b1a: b083 sub sp, #12 15b1c: f04f 0001 mov.w r0, #1 15b20: f7ec fd96 bl 2650 <operator new(unsigned long)> 15b24: 4603 mov r3, r0 15b26: 461a mov r2, r3 15b28: f04f 0105 mov.w r1, #5 15b2c: 7011 strb r1, [r2, #0] 15b2e: 9300 str r3, [sp, #0] 15b30: 9b00 ldr r3, [sp, #0] 15b32: 2b00 cmp r3, #0 15b34: d02a beq.n 15b8c <goto_test()+0x74> 15b36: f04f 0001 mov.w r0, #1 15b3a: f7ec fd89 bl 2650 <operator new(unsigned long)> 15b3e: 4603 mov r3, r0 15b40: 461a mov r2, r3 15b42: f04f 0105 mov.w r1, #5 15b46: 7011 strb r1, [r2, #0] 15b48: 9301 str r3, [sp, #4] 15b4a: 9b01 ldr r3, [sp, #4] 15b4c: 2b00 cmp r3, #0 15b4e: d017 beq.n 15b80 <goto_test()+0x68> 15b50: f04f 0001 mov.w r0, #1 15b54: f7ec fd7c bl 2650 <operator new(unsigned long)> 15b58: 4603 mov r3, r0 15b5a: 461a mov r2, r3 15b5c: f04f 0105 mov.w r1, #5 15b60: 7011 strb r1, [r2, #0] 15b62: 9302 str r3, [sp, #8] 15b64: 9b02 ldr r3, [sp, #8] 15b66: 2b00 cmp r3, #0 15b68: d004 beq.n 15b74 <goto_test()+0x5c> 15b6a: 9b02 ldr r3, [sp, #8] 15b6c: 4618 mov r0, r3 15b6e: f7ec fd83 bl 2678 <operator delete(void*)> 15b72: e000 b.n 15b76 <goto_test()+0x5e> 15b74: bf00 nop 15b76: 9b01 ldr r3, [sp, #4] 15b78: 4618 mov r0, r3 15b7a: f7ec fd7d bl 2678 <operator delete(void*)> 15b7e: e000 b.n 15b82 <goto_test()+0x6a> 15b80: bf00 nop 15b82: 9b00 ldr r3, [sp, #0] 15b84: 4618 mov r0, r3 15b86: f7ec fd77 bl 2678 <operator delete(void*)> 15b8a: e000 b.n 15b8e <goto_test()+0x76> 15b8c: bf00 nop 15b8e: b003 add sp, #12 15b90: bd00 pop {pc} 15b92: bf00 nop
00015b94 <no_goto_test()>: 15b94: b500 push {lr} 15b96: b083 sub sp, #12 15b98: f04f 0001 mov.w r0, #1 15b9c: f7ec fd58 bl 2650 <operator new(unsigned long)> 15ba0: 4603 mov r3, r0 15ba2: 461a mov r2, r3 15ba4: f04f 0105 mov.w r1, #5 15ba8: 7011 strb r1, [r2, #0] 15baa: 9300 str r3, [sp, #0] 15bac: 9b00 ldr r3, [sp, #0] 15bae: 2b00 cmp r3, #0 15bb0: d025 beq.n 15bfe <no_goto_test()+0x6a> 15bb2: f04f 0001 mov.w r0, #1 15bb6: f7ec fd4b bl 2650 <operator new(unsigned long)> 15bba: 4603 mov r3, r0 15bbc: 461a mov r2, r3 15bbe: f04f 0105 mov.w r1, #5 15bc2: 7011 strb r1, [r2, #0] 15bc4: 9301 str r3, [sp, #4] 15bc6: 9b01 ldr r3, [sp, #4] 15bc8: 2b00 cmp r3, #0 15bca: d014 beq.n 15bf6 <no_goto_test()+0x62> 15bcc: f04f 0001 mov.w r0, #1 15bd0: f7ec fd3e bl 2650 <operator new(unsigned long)> 15bd4: 4603 mov r3, r0 15bd6: 461a mov r2, r3 15bd8: f04f 0105 mov.w r1, #5 15bdc: 7011 strb r1, [r2, #0] 15bde: 9302 str r3, [sp, #8] 15be0: 9b02 ldr r3, [sp, #8] 15be2: 2b00 cmp r3, #0 15be4: d003 beq.n 15bee <no_goto_test()+0x5a> 15be6: 9b02 ldr r3, [sp, #8] 15be8: 4618 mov r0, r3 15bea: f7ec fd45 bl 2678 <operator delete(void*)> 15bee: 9b01 ldr r3, [sp, #4] 15bf0: 4618 mov r0, r3 15bf2: f7ec fd41 bl 2678 <operator delete(void*)> 15bf6: 9b00 ldr r3, [sp, #0] 15bf8: 4618 mov r0, r3 15bfa: f7ec fd3d bl 2678 <operator delete(void*)> 15bfe: b003 add sp, #12 15c00: bd00 pop {pc} 15c02: bf00 nop
00015c04 <main>: 15c04: b500 push {lr} 15c06: b081 sub sp, #4 15c08: f7ff ff86 bl 15b18 <goto_test()> 15c0c: f7ff ffc2 bl 15b94 <no_goto_test()> ...
|  |  |  |  |
Вижда се, че кодът с goto е по-голям и съответно по-неефиктивен, което даже и мен ме учуди  В интерес на истината при включени оптимизации, няма **никаква** разлика:  |  |  |  | Код: 000146c4 <no_goto_test()>: 146c4: b570 push {r4, r5, r6, lr} 146c6: 2001 movs r0, #1 146c8: f7ed ffc2 bl 2650 <operator new(unsigned long)> 146cc: 2405 movs r4, #5 146ce: 4605 mov r5, r0 146d0: 7004 strb r4, [r0, #0] 146d2: 2001 movs r0, #1 146d4: f7ed ffbc bl 2650 <operator new(unsigned long)> 146d8: 4606 mov r6, r0 146da: 7004 strb r4, [r0, #0] 146dc: 2001 movs r0, #1 146de: f7ed ffb7 bl 2650 <operator new(unsigned long)> 146e2: 7004 strb r4, [r0, #0] 146e4: f7ed ffc8 bl 2678 <operator delete(void*)> 146e8: 4630 mov r0, r6 146ea: f7ed ffc5 bl 2678 <operator delete(void*)> 146ee: 4628 mov r0, r5 146f0: f7ed ffc2 bl 2678 <operator delete(void*)> 146f4: bd70 pop {r4, r5, r6, pc} 146f6: bf00 nop
000146f8 <goto_test()>: 146f8: b570 push {r4, r5, r6, lr} 146fa: 2001 movs r0, #1 146fc: f7ed ffa8 bl 2650 <operator new(unsigned long)> 14700: 2405 movs r4, #5 14702: 4605 mov r5, r0 14704: 7004 strb r4, [r0, #0] 14706: 2001 movs r0, #1 14708: f7ed ffa2 bl 2650 <operator new(unsigned long)> 1470c: 4606 mov r6, r0 1470e: 7004 strb r4, [r0, #0] 14710: 2001 movs r0, #1 14712: f7ed ff9d bl 2650 <operator new(unsigned long)> 14716: 7004 strb r4, [r0, #0] 14718: f7ed ffae bl 2678 <operator delete(void*)> 1471c: 4630 mov r0, r6 1471e: f7ed ffab bl 2678 <operator delete(void*)> 14722: 4628 mov r0, r5 14724: f7ed ffa8 bl 2678 <operator delete(void*)> 14728: bd70 pop {r4, r5, r6, pc} 1472a: bf00 nop
|  |  |  |  |
|
| Пон Сеп 20, 2010 6:43 pm |
|
 |
|
relsys
Ранг: Форумен бог
Регистриран на: Пет Ное 25, 2005 11:41 am Мнения: 1680
|
Някой беше казал, че е практически невъзможно да се обучат студентите на добро програмиране, които са писали преди това на BASIC. Въпреки, че и аз с това съм започнал, и последните 10 г. пиша само FIRMWARE, съм ползвал goto с коефициент 1 : 50 000. Или иначе казано - по 1 goto на 50 000 реда код. И вероятно и то е можело да бъде избегнато. То да вземем и номера на редовете да пишем, че по-лесно. Сега имам един колега на 20 години, утре ще го питам дали въобще е чувал за goto, защото например не знаеше, че $ == 0х.....
Та, мисля с goto-то ясно....
Предлагам да прехвърлим дискусията на това, как да си пишем функциите: BLOCKING или NON-BLOCKING?
|
| Пон Сеп 20, 2010 8:49 pm |
|
 |
|
¶
Ранг: Форумен бог
Регистриран на: Пет Фев 25, 2005 1:58 pm Мнения: 4585 Местоположение: US
|
Ами много програмисти се мръщят на goto щото като са учили езика са го пропуснали. На мен не ми прави никакво впечатление дали се употрябава често goto или не, въпреки че не се сещам кога за последно ми се е налагало да го използвам. В крайна сметка това е речника на езика, на който не му харесва използвания речник да пише на Питон, Паскал, Фортран, Кобол или каквото там му харесва. Или да си направи собствен език, в който да липсва оператора
Ако на някой му се рови, мисля преди 2-3г. се изписаха поне няколко стрници за и против goto. Ако намери линка да го пусне тука, ще си спестим много от сапуня 
_________________ Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....
|
| Пон Сеп 20, 2010 8:51 pm |
|
 |
|
Zeus
Ранг: Почетен член
Регистриран на: Вто Окт 03, 2006 11:58 am Мнения: 924 Местоположение: Ботевград
|
А спомняте ли си класиката от Бейсик
.....
10 LET A=10
.....
Направо ми потичат сълзи от умиление
Ta goto доста ми напомня тоя LET: може и с него, може и без него
|
| Пон Сеп 20, 2010 9:00 pm |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
То и в българския речник има разни нецензурни думички, дето не харесвам, ама значи ли че трябва да престана да използвам български
Oбадих се щото не обичам предразсъдъците... като расизма (и негрите, ама това е друга тема  )
Нека всеки да ползва каквото си ще... Goto е въпрос на вкус, няма техническа причина да бъде ползван. По-скоро както показах в горния пример може да подведе компилатора, да не се използват инструкции с условно изпълнение и т.н.
Между другото, стандартното приложение на goto си е сложни вложени цикли. Недостатъкът на Ц-то е липсата на читав break. Пирев сега ще каже да ползвам друг език, но аз действително ползвам и други езици като PHP дето го няма тоя проблем  Но да се върнем на Ц-то, значи аз не ползвам goto дори и в тия случаи. Ползвам нещо още по-кофти и от goto - вложени функции. По-кофти е, защото не са стандартни, има ги само GCC. Но просто, не мога да устоя на навика от Pascal... Иначе идеята е просто - циклите в една вложена функция и когато искам да изляза, излизам с return... Освен, че е нестандартен тоя метод няма никакви недостатъци за изпълнимия код, даже напротив ГЦЦ прави по-добър код, по-добре се ориентира кои променливи къде да разполага и т.н.
Ако трябва да бъда прецизен при тоя похват се ползва още едно анатемосано нещо - да се слага повече от един return в една функция  Та както казах, от "вкусова" гледна точка аз имам по-лош вкус 
|
| Пон Сеп 20, 2010 10:19 pm |
|
 |
|
Cekins
Ранг: Форумен бог
Регистриран на: Сря Апр 20, 2005 12:02 pm Мнения: 9119 Местоположение: Разград
|
Е аз доколкото си спомням в байсика за осмака беше неизбежно. Може би заради факта че е интерпретатор. Там стила на писане и мнооого далеч от тия бейсици дето сега толкова много се оплюват. Аз гото ползвам 1 път в програмата - за главния лууп. Ама то там какъв ще е безкрайния цикъл няма никакво значение. А в случай без goto, дали компилатора там не ползва пак някакъв тип безусловен преход?
|
| Пон Сеп 20, 2010 10:23 pm |
|
 |
|
emilvtc
Ранг: Форумен бог
Регистриран на: Вто Фев 06, 2007 8:44 pm Мнения: 3175 Местоположение: Пловдив
|
Миро, и какво му е лошото на многократното използване на "return" в една функция, та го смяташ за "анатемосано"? Аз например го смятам за много ефективен начин за изход от функция, който повишава и четимостта.
Относно избягването на гото-то с цената на извикване на функция за което говориш ми се струва супер неефективно решение ... Предаване на параметри на функцията през стека (или през глобални променливи), после връщане на параметри, преход и връщане от функция ...
Разбирам процесора да си няма ASM инструкция за безусловен преход, ама такъв процесор още не ми е известен... И защо да отбягваме използването на еквивалента и в езиците от високо ниво? Щом ви харесва да не използвате гото - недейте. Само не подвеждайте хората, че не бива да се използва ... Ако някой живее с мисълта, че при компилирането на сорс код без goto компилатора няма да използва инструкции за безусловен преход - да не си го мисли повече.
Относно примера който даваш - резултата може и да е такъв, но аз мога да ти дам и друг пример демонстриращ противното... Наистина смятам, че няма защо повече да "дъвчем" темата.
както сам казваш - въпрос на вкус 
|
| Пон Сеп 20, 2010 10:41 pm |
|
 |
|
sv_shady
Ранг: Популярен
Регистриран на: Сря Окт 11, 2006 8:19 pm Мнения: 373 Местоположение: София/Edinburgh, UK
|
@emilvtc Би ми било наистина много интересно да видя такъв код. Често ми се налага да оптимизирам, така че би ми било интересно кога goto е по-ефективно.
|
| Пон Сеп 20, 2010 10:55 pm |
|
 |
|
Cekins
Ранг: Форумен бог
Регистриран на: Сря Апр 20, 2005 12:02 pm Мнения: 9119 Местоположение: Разград
|
@emilvtc ползват и още как  При всеки по сложно конструиран IF най-бързия начин да се прескочи едната условност е с гото към другата ... Особенно при малките алу-та.
|
| Пон Сеп 20, 2010 11:27 pm |
|
 |
|
Zdrav
Ранг: Форумен бог
Регистриран на: Сря Яну 26, 2005 2:01 pm Мнения: 1952 Местоположение: Варна
|
Добре де... засега тука говорите за bailout с goto. Да ама goto позволява и обратното. Не само да се спасяваш от вложени цикли и case-ове но goto ти дава безграничната свобода и да влизаш в тях. Да цопваш с двата крака където си поискаш. Именно това според мен са имали предвид умните глави, когато са давали препоръки да се избягва употребата му.
_________________ Най-опасният враг на истината и свободата е мнозинството.
|
| Вто Сеп 21, 2010 12:10 am |
|
 |
|
miro_atc
Ранг: Форумен бог
Регистриран на: Нед Фев 26, 2006 6:52 pm Мнения: 11266 Местоположение: Добрич
|
Алу-то няма значение. Това което има значение е компилаторът. Ако компилаторът е читав, той ще се осети как да подреди кода, *незвисимо* как си го разположил. Анатемосват го, тъй като е често голям източник на грешки тип "недоглеждане". Обикновено една функция има някакво встъпление, нещо като същинска част и някакъв cleanup код накрая. Проблемът е, че всичко се прави по стереотип и не се помни от програмиста. Съответно като се наложи промяна лесно става фал, защото примерно добавяш още нещо дето трябва да се почисти в cleanup-а и ти наистина го добавяш там, само че не си видял, че има още един return скрит някъде и който обикновено не се ползва в ситуацията и не го дебъгваш/тестваш и ти гърми чак след месец при клиента... Аз лично почнах да избягвам многото return-и след като почнах да ползвам усилено трейс. Слагам масово ENTER_FUNCTION() и LEAVE_FUNCTION() - макросчета, дето трасират откъде си минал и то по прегледен начин... Само че, с тия екстри дебъг версията ми почва да става значително по-обемиста, а някак си не върви да се презапасявам с флаш. Да не говорим, че обикновено не ги ползвам тия макроси, а ги добавям след като няколко хиляди реда код откажат да работят стабилно. И като пропусна да сложа някъде макросче, ми прави и фалшиви тревоги... Вложените функции (функция във функция) нямат нищо общо с нормалните функции, по-скоро са нещо като като макрос. Особено ако се викат от едно-две места... Виж ако има рекурсия или други подобни, ще има предаване на параметри, но дори и тогава е по-оптимално от нормалните функции или в най-лошия случай колкото static функции. GCC оптимизира static функции както намери за добре. Не се съобразява нито с calling конвенции, нито с параметри...
Това което се опитвам да ти обясня е, че няма **НИКАКВА** връзка между goto и безусловния преход на асемблера. Това, че ти ще напишеш goto на Ц не означава, че то ще използва безусловен преход. Ако си спомням добре ти имаше някаква представа от АРМ, така че може да прегледаш горния код. Забележи, че безусловните преходи изобщо не са там, където би трябвало да бъдат.... А там където има безусловни преходи, очевидно е простотия да ги има и тя е причинена от goto-то
|
| Вто Сеп 21, 2010 12:22 am |
|
 |
|
relsys
Ранг: Форумен бог
Регистриран на: Пет Ное 25, 2005 11:41 am Мнения: 1680
|
Само ти не подвеждай хората, че трябва да се използва....
А както и предполагах, дори не го преподават в училищата по програмиране това 'goto', че съществува....
http://i.techrepublic.com.com/blogs/goto.png
|
| Вто Сеп 21, 2010 8:45 am |
|
 |
|
Цецо
Ранг: Форумен бог
Регистриран на: Пон Сеп 27, 2004 9:22 am Мнения: 15501 Местоположение: София
|
Абе добре ли е да се пие бира преди секс?
Мисля, че тоя въпрос ще породи много по полезна и смислена дискусия.
_________________ "Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.
|
| Вто Сеп 21, 2010 10:14 am |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 3 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|