Отговори на тема  [ 46 мнения ]  Отиди на страница Предишна  1, 2, 3, 4  Следваща
Използване на goto и labels в C 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Юни 10, 2007 2:22 pm
Мнения: 6492
Местоположение: София
Мнение 
emilvtc написа:
... Пирев хубаво го каза това за "мечките и гората" :-)

Не мога да схвана каква е тази самоцел - дайте да се гърчим и да мислим идиотски констрикции от оператири само за да не използваме Goto ? Това ми звучи малко смахнато, не мислите ли ?


То в тоя ред на мисли гърчът да се навре написването на роман във фразите предлагани
в разговорника - избягвайки една заклеймена като лоша - е истински "смахнатото".

_________________
-------------------
www.tgi-sci.com
-------------------
http://www.flickr.com/photos/didi_tgi/


Пон Сеп 20, 2010 5:44 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
emilvtc написа:

Разбира се, че правилното му използване води до по-ефективен код като скорост.
Разбира се и че правилното му използване води и до по-ефективен код като размер.
Та на всичко отгоре може да доведе и до по-четим код ... Зависи от случая ...

При писането на код трябва да се стремим да правим "оптимизация" още на ниво сорс. Goto може много да ни помогне в това отношение. Тъпо е според мен да се разчита само на оптимизацията на компилатора при компилиране.



Ако мислиш, че ще направиш кода си по-четим използвай 'goto' няма проблем! Но имай предвид, че това е много субективно. Нещо дето е четимо за теб, може да е много нечетимо за други. Като се има предвид, че много С/С++ програмисти ненавиждат 'goto' то познай колко четим ще е твоя код за другите ;-)

Що се отнася до другите твърдения, повярвай ми *НЯМА* нищо вярно в тях, поне не и за съвременните компилатори. А ако не ми вярваш, да ми код с 'goto', аз ще го пренапиша без гото и ще сравним листингите...


Пон Сеп 20, 2010 6:05 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
И тъй като не обичам да приказвам празни приказки взех примера на @radolin:

Код:
void goto_test()
{
   char * resource[3];


   resource[0] = new char(5);
   if(!resource[0])
      goto l0;

   resource[1] = new char(5);
   if(!resource[1])
      goto l1;

   resource[2] = new char(5);
   if(!resource[2])
      goto l2;

   // real stuff here

   delete resource[2];
l2:
   delete resource[1];
l1:
   delete resource[0];
l0:
   ;
}

void no_goto_test()
{
   char * resource[3];

   resource[0] = new char(5);
   if(resource[0])
   {
      resource[1] = new char(5);
      if(resource[1])
      {
         resource[2] = new char(5);
         if(resource[2])
         {

            // real stuff here

            delete resource[2];
         }

         delete resource[1];
      }
      delete resource[0];
   }
}









int main(void)
{

   goto_test();
   no_goto_test();
.....
}




ето и резултата:

Код:
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
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 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
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
Ами много програмисти се мръщят на goto щото като са учили езика са го пропуснали. На мен не ми прави никакво впечатление дали се употрябава често goto или не, въпреки че не се сещам кога за последно ми се е налагало да го използвам. В крайна сметка това е речника на езика, на който не му харесва използвания речник да пише на Питон, Паскал, Фортран, Кобол или каквото там му харесва. Или да си направи собствен език, в който да липсва оператора :D

Ако на някой му се рови, мисля преди 2-3г. се изписаха поне няколко стрници за и против goto. Ако намери линка да го пусне тука, ще си спестим много от сапуня :-)

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Пон Сеп 20, 2010 8:51 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Вто Окт 03, 2006 11:58 am
Мнения: 924
Местоположение: Ботевград
Мнение 
А спомняте ли си класиката от Бейсик

.....
10 LET A=10
.....

Направо ми потичат сълзи от умиление :)


Ta goto доста ми напомня тоя LET: може и с него, може и без него


Пон Сеп 20, 2010 9:00 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
¶ написа:
В крайна сметка това е речника на езика, на който не му харесва използвания речник да пише на Питон, Паскал, Фортран, Кобол или каквото там му харесва. Или да си направи собствен език, в който да липсва оператора :D


То и в българския речник има разни нецензурни думички, дето не харесвам, ама значи ли че трябва да престана да използвам български :D

Oбадих се щото не обичам предразсъдъците... като расизма (и негрите, ама това е друга тема ;-) )

Нека всеки да ползва каквото си ще... Goto е въпрос на вкус, няма техническа причина да бъде ползван. По-скоро както показах в горния пример може да подведе компилатора, да не се използват инструкции с условно изпълнение и т.н.

Между другото, стандартното приложение на goto си е сложни вложени цикли. Недостатъкът на Ц-то е липсата на читав break. Пирев сега ще каже да ползвам друг език, но аз действително ползвам и други езици като PHP дето го няма тоя проблем ;-) Но да се върнем на Ц-то, значи аз не ползвам goto дори и в тия случаи. Ползвам нещо още по-кофти и от goto - вложени функции. По-кофти е, защото не са стандартни, има ги само GCC. Но просто, не мога да устоя на навика от Pascal... Иначе идеята е просто - циклите в една вложена функция и когато искам да изляза, излизам с return... Освен, че е нестандартен тоя метод няма никакви недостатъци за изпълнимия код, даже напротив ГЦЦ прави по-добър код, по-добре се ориентира кои променливи къде да разполага и т.н.

Ако трябва да бъда прецизен при тоя похват се ползва още едно анатемосано нещо - да се слага повече от един return в една функция ;-) Та както казах, от "вкусова" гледна точка аз имам по-лош вкус ;-)


Пон Сеп 20, 2010 10:19 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение 
Е аз доколкото си спомням в байсика за осмака беше неизбежно. Може би заради факта че е интерпретатор. Там стила на писане и мнооого далеч от тия бейсици дето сега толкова много се оплюват. Аз гото ползвам 1 път в програмата - за главния лууп. Ама то там какъв ще е безкрайния цикъл няма никакво значение. А в случай без goto, дали компилатора там не ползва пак някакъв тип безусловен преход?


Пон Сеп 20, 2010 10:23 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Фев 06, 2007 8:44 pm
Мнения: 3175
Местоположение: Пловдив
Мнение 
Миро, и какво му е лошото на многократното използване на "return" в една функция, та го смяташ за "анатемосано"? Аз например го смятам за много ефективен начин за изход от функция, който повишава и четимостта.

Относно избягването на гото-то с цената на извикване на функция за което говориш ми се струва супер неефективно решение ... Предаване на параметри на функцията през стека (или през глобални променливи), после връщане на параметри, преход и връщане от функция ...
Разбирам процесора да си няма ASM инструкция за безусловен преход, ама такъв процесор още не ми е известен... И защо да отбягваме използването на еквивалента и в езиците от високо ниво? Щом ви харесва да не използвате гото - недейте. Само не подвеждайте хората, че не бива да се използва ... Ако някой живее с мисълта, че при компилирането на сорс код без goto компилатора няма да използва инструкции за безусловен преход - да не си го мисли повече.

Относно примера който даваш - резултата може и да е такъв, но аз мога да ти дам и друг пример демонстриращ противното... Наистина смятам, че няма защо повече да "дъвчем" темата.
както сам казваш - въпрос на вкус :-)


Пон Сеп 20, 2010 10:41 pm
Профил
Ранг: Популярен
Ранг: Популярен
Аватар

Регистриран на: Сря Окт 11, 2006 8:19 pm
Мнения: 373
Местоположение: София/Edinburgh, UK
Мнение 
@emilvtc Би ми било наистина много интересно да видя такъв код. Често ми се налага да оптимизирам, така че би ми било интересно кога goto е по-ефективно.

_________________
Българският портал за РОБОТИКА


Пон Сеп 20, 2010 10:55 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение 
@emilvtc ползват и още как :) При всеки по сложно конструиран IF най-бързия начин да се прескочи едната условност е с гото към другата ... Особенно при малките алу-та.


Пон Сеп 20, 2010 11:27 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 2:01 pm
Мнения: 1952
Местоположение: Варна
Мнение 
Добре де... засега тука говорите за bailout с goto. Да ама goto позволява и обратното. Не само да се спасяваш от вложени цикли и case-ове но goto ти дава безграничната свобода и да влизаш в тях. Да цопваш с двата крака където си поискаш. Именно това според мен са имали предвид умните глави, когато са давали препоръки да се избягва употребата му.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Вто Сеп 21, 2010 12:10 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11266
Местоположение: Добрич
Мнение 
Cekins написа:
При всеки по сложно конструиран IF най-бързия начин да се прескочи едната условност е с гото към другата ... Особенно при малките алу-та.


Алу-то няма значение. Това което има значение е компилаторът. Ако компилаторът е читав, той ще се осети как да подреди кода, *незвисимо* как си го разположил.


emilvtc написа:
Миро, и какво му е лошото на многократното използване на "return" в една функция, та го смяташ за "анатемосано"? Аз например го смятам за много ефективен начин за изход от функция, който повишава и четимостта.


Анатемосват го, тъй като е често голям източник на грешки тип "недоглеждане". Обикновено една функция има някакво встъпление, нещо като същинска част и някакъв cleanup код накрая. Проблемът е, че всичко се прави по стереотип и не се помни от програмиста. Съответно като се наложи промяна лесно става фал, защото примерно добавяш още нещо дето трябва да се почисти в cleanup-а и ти наистина го добавяш там, само че не си видял, че има още един return скрит някъде и който обикновено не се ползва в ситуацията и не го дебъгваш/тестваш и ти гърми чак след месец при клиента...
Аз лично почнах да избягвам многото return-и след като почнах да ползвам усилено трейс. Слагам масово ENTER_FUNCTION() и LEAVE_FUNCTION() - макросчета, дето трасират откъде си минал и то по прегледен начин... Само че, с тия екстри дебъг версията ми почва да става значително по-обемиста, а някак си не върви да се презапасявам с флаш. Да не говорим, че обикновено не ги ползвам тия макроси, а ги добавям след като няколко хиляди реда код откажат да работят стабилно. И като пропусна да сложа някъде макросче, ми прави и фалшиви тревоги...



Цитат:
Относно избягването на гото-то с цената на извикване на функция за което говориш ми се струва супер неефективно решение ... Предаване на параметри на функцията през стека (или през глобални променливи), после връщане на параметри, преход и връщане от функция ...

Вложените функции (функция във функция) нямат нищо общо с нормалните функции, по-скоро са нещо като като макрос. Особено ако се викат от едно-две места... Виж ако има рекурсия или други подобни, ще има предаване на параметри, но дори и тогава е по-оптимално от нормалните функции или в най-лошия случай колкото static функции.
GCC оптимизира static функции както намери за добре. Не се съобразява нито с calling конвенции, нито с параметри...


Цитат:
Само не подвеждайте хората, че не бива да се използва ... Ако някой живее с мисълта, че при компилирането на сорс код без goto компилатора няма да използва инструкции за безусловен преход - да не си го мисли повече.


Това което се опитвам да ти обясня е, че няма **НИКАКВА** връзка между goto и безусловния преход на асемблера. Това, че ти ще напишеш goto на Ц не означава, че то ще използва безусловен преход. Ако си спомням добре ти имаше някаква представа от АРМ, така че може да прегледаш горния код. Забележи, че безусловните преходи изобщо не са там, където би трябвало да бъдат.... А там където има безусловни преходи, очевидно е простотия да ги има и тя е причинена от goto-то


Вто Сеп 21, 2010 12:22 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 25, 2005 11:41 am
Мнения: 1680
Мнение 
emilvtc написа:
.... Само не подвеждайте хората, че не бива да се използва ...


Само ти не подвеждай хората, че трябва да се използва....

А както и предполагах, дори не го преподават в училищата по програмиране това 'goto', че съществува.... :idea:

http://i.techrepublic.com.com/blogs/goto.png


Вто Сеп 21, 2010 8:45 am
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Абе добре ли е да се пие бира преди секс?

Мисля, че тоя въпрос ще породи много по полезна и смислена дискусия.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Вто Сеп 21, 2010 10:14 am
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 46 мнения ]  Отиди на страница Предишна  1, 2, 3, 4  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни