1. PHP / Говнокод #23798

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    // http://www.compiler.su/prodolzhenie-tsikla-i-vykhod-iz-nego.php
    // В PHP выход из вложенного цикла выглядит, на мой взгляд, значительно элегантнее. После «break» указывается количество вложенных циклов, которые должен «покинуть» оператор «break». В приведённом примере, который аналогичен приведённому выше для Java, «break» должен «пересечь» две фигурные скобки «}», чтобы оказаться за пределами двух циклов.
    
    for($i=0; $i < $Imax; ++$i)
    {
       // ...
       for($j=0; $j < $Jmax; ++$j)
       {
          // ...
          if(условие) 
              break 2;
          // ...
       }
       // ...
    }

    Интересно, а почему б нечто подобное не сделать для функций? Ну например есть функция a() которая вызывает функцию b() которая вызывает функцию c(), которая вызывает функцию d(), и например в функции d() чтоб сделать особый return_3, который бы вернул управление на три уровня вниз, сразу в функцию a()? Хотя не, хуйня, надо ведь еще знать, какой там тип возвращается в функцию a() из функции b().
    То ли дело ассемблер. Можно тупо отмотать стек в нужное место

    Запостил: j123123, 16 Февраля 2018

    Комментарии (64) RSS

    • break метка лучше
      Ответить
      • Тогда это будет как goto, а goto это плохо, пнятненько? Зачем мне goto, у меня нет времени чтобы ебаться с ним, лучше добавим какой-нибудь дополнительной синтаксической хуйни в язык!
        Ответить
    • Блять, ну пхп как всегда: даже в таком простом и то умудрились хуйню сделать.
      Еще и доказывают превосходство.
      // В PHP выход из вложенного цикла выглядит, на мой взгляд, значительно элегантнее


      >PHP
      > элегантно
      Ыыы..
      Ответить
    • >Ну например есть функция a() которая вызывает функцию b() которая вызывает функцию c(), которая вызывает функцию d(), и например в функции d() чтоб сделать особый return_3, который бы вернул управление на три уровня вниз, сразу в функцию a()?

      Троллейбус из хлеба какой-то.


      >То ли дело ассемблер. Можно тупо отмотать стек в нужное место
      throw return_3;
      Но сишникам не понять.
      Стандартная практика как брейкать циклы из лямбдовых for-each.
      Ответить
      • Элегантный longjmp.
        Ответить
        • всегда было интересно: а если положить jmp_buf в кучу или статическую область модуля, и попытаться прыгнуть в уже завершенную функцию, то что будет?
          Из ниокуда реально вернется ее стек? или будет UB?
          Ответить
          • продаю свои ношеные трусы для любителей пикантненького, 5тр, сам гей, смазлив, ухожен, пиши прямо сейчас [email protected] антон ЖДУ
            Ответить
          • давайте перефразирую

            jmp_buf хранит и укойзатель насуществующий стек и просто отматывает его в нужное место, или там реально где-то в кишках рантаймы сохраняется весь стек до этого места?

            Наверняка же нет, да?
            Ответить
            • парень в сексуальном кружавчике обслужит парня или группу парней предпочтение кавказцам все позы секс-практики и секс-игрушки, любые желания за твои деньги! пиши прямо сейчас [email protected] антон ЖДУ
              Ответить
            • Да, просто отматывает стек. Это не continuation, при повторном вызове просто распидорасит.
              Ответить
              • парень в сексуальном кружавчике обслужит парня или группу парней предпочтение кавказцам все позы секс-практики и секс-игрушки, любые желания за твои деньги! пиши прямо сейчас [email protected] антон ЖДУ
                Ответить
              • Скучно
                Хочу прыгать в стек другого потока
                Ответить
              • Брманд, а ты знаешь про setcontext/getcontext?
                Они делают то, о чем я говорил. И из них можно делать континиуэйшены
                Ответить
      • Кстати, цитируемый текст был написан всерьёз? Я даже не знаю, это так вореции сишки на людей действуют, или то был сарказм.
        На ум из аналогичного приходят разве что исключения.
        Но всё равно какая-то питушня. Функция по сути должна знать, кто её вызывает, чтобы принять такие решения. То есть должна быть жёстко закреплена в кобенном строе программы - никаких переиспользований, никаких абстракция - вся архитектура к хренам! Я такой уровень самоуправства только у функций, которые exit делают, и то они не более, чем void, возвращали.
        Ответить
        • Чтобы можно было в функции d() вызывать return_3, надо гарантировать что фукнция, лежащая тремя уровнями ниже по стеку вызовов, вызывает в том месте некую функцию с точно такой же сигнатурой, что и сигнатура функции d(), и это вполне можно проверить на этапе компиляции
          int a(int val)
          {
            int test = b(val);
            return test;
          }
          
          int b(int val)
          {
            int test = c(val+5);
            return test;
          }
          
          int c(int val)
          {
            int test = d(val+123);
            return test;
          }
          
          int d(int val)
          {
            if(val = 666)
            {
              return_3 6666;  // отсюда сразу происходит возврат в функцию int a(int val)
            }
            return val + 5;
          }

          но могут возникнуть сложности, если используется вызов функций по указателям.
          Ответить
          • Синтаксически это полная хуйня, но идея, думаю ясна.
            DeepReturnInt{
              int depth;
              T result;
            }
            
            #define DEEP_FUN(x)    try{ (x)  }                       \
            catch(DeepReturnInt  r){                                      \
                if (--r.depth>0) throw r; else return r.result;        \
            }
            
            int a(int val)
            {
                DEEP_FUN(
                    int test = b(val);
                    return test;
                )
            }
            
            int b(int val)
            {
                DEEP_FUN(
                  int test = c(val+5);
                  return test;
                )
            }
            
            int c(int val)
            {
                DEEP_FUN(
                  int test = c(val*5);
                  return test;
                )
            }
            
            int d(int val)
            {
              if(val = 666)
              {
                throw DeepReturnInt(3, 6666);  // отсюда сразу происходит возврат в функцию int a(int val)
              }
              return val + 5;
            }


            Думаю макросом и шаблонами можно даже добиться нормально проверяемой компилятором тупизации.
            Ответить
        • > Функция по сути должна знать, кто её вызывает

          Это не особо-то и сложно, учитывая что в стеке есть адрес возврата, а "кто кого откуда может вызвать" можно узнать на этапе компиляций, кроме случаев, где происходят какие-нибудь вызовы функций по указателям
          Ответить
          • Я именно про перспективы архитектуры говорил. Что реализовать такое можно, я верю, но зачем это нужно - не понимаю.
            В моём представлении это способ сломать абстракции и контракты, добавление новых рёбер в граф зависимостей.
            Вот, например, брала функция корень и если обнаруживала NaN, возвращала ноль. А тут вдруг корень в версии 2.0 стал в случае отрицательного операнда возвращать NaN сразу из нашей функции. И это никак не остановить. Абстракция протекает, не заткнёшь. Исключения и те резиновой пробкой затыкаются на любом уровне.
            Единственное, что приходит в голову - какие-то подсказки компилятору для оптимизаций: в случае математических функций - по поводу пронесения NaN, в случае функций для работу с памятью - по поводу пронесения NULL. Но это если исключения и оптимизация по умолчанию тупые и медленные.
            Ответить
          • >>учитывая что в стеке есть адрес возврата,
            если не херить BP (не включать FPO) то можно раскрутить весь стек до самого первого вызова жи.

            зы:
            "и еще хорошо если в стеке есть адрес возврата" (с)
            Ответить
            • парень в сексуальном кружавчике обслужит парня или группу парней предпочтение кавказцам все позы секс-практики и секс-игрушки, любые желания за твои деньги, презы с меня! пиши прямо сейчас [email protected] антон ЖДУ
              Ответить
        • http://govnokod.ru/19299 а еще всегда можно внутри функций сделать свои псевдофункции через стековую машину, и там уже легко можно отматывать стек и прыгать куда надо, или вообще писать на асме
          Ответить
        • Годное текстуальное упарывание. Оценил.

          Думаю всё можно и даже нужно. Представим себе жс
          function make(b){
              var inner=b;
                function a(func){
                    inner=func(inner); console.log(inner);
                    return a;
               }     
              return a;
          }
          a=make (4)
          a(Math.sqrt)(Math.cos)(Math.acos)


          По сути у нас цепочка однотипных функций (с одинаковыми сигнатурами!).
          a().b().c().d()
          А внутри монадка горит. А мы хотим скипнуть N вычислений.

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

          Думаю разные высокоуровневые языки запросто решат проблемы с питульной типизацией однотипных функций.
          Ответить
          • А чем это лучше исключений и оптимизации в компиляторах?
            Кстати, в C++ можно с его развитыми кастами типы по всей цепочке гнать автоматически.
            Ответить
            • парень в сексуальном кружавчике обслужит парня или группу парней предпочтение кавказцам все позы секс-практики и секс-игрушки, любые желания за твои деньги! пиши прямо сейчас [email protected] антон ЖДУ
              Ответить
    • https://ideone.com/IIZcwW

      А изнутри это все равно та же самая раскрутка стека. Согласно теории ЯП. Хотя я сужу по С++, и не могу точно сказать, как это реализовано в пхп.

      Да и исключения, из-за той же раскрутки стека - это очень прожорливая вещь.
      https://habrahabr.ru/post/208006/
      Ответить
      • Каждый return тоже раскручивает стек, как бы.
        Ответить
        • но не сильно, на пару сотен байт всего
          Ответить
        • И фигурные скобочки тоже.
          Ответить
        • совершенно верно

          потому call/ret это вообще плохо, цари инлайнят функции
          Ответить
    • ПХПГОВНО
      Ответить
    • http://govnokod.ru/985
      И ещё несколько раз было.
      Ответить
    • Прикольно, не знал что так можно. Буду юзать.
      Ответить
    • А можно break $count?
      Ответить
    • А ещё goto в PHP завезли только в 5.3.0
      Ответить
      • А зачем?
        Ответить
      • https://secure.php.net/manual/ru/control-structures.goto.php
        > Оператор не является неограниченным "goto". Целевая метка должна находиться в том же файле, в том же контексте. Имеется в виду, что вы не можете ни перейти за границы функции или метода, ни перейти внутрь одной из них. Вы также не можете перейти внутрь любой циклической структуры или оператора switch. Но вы можете выйти из них, и обычным применением оператора goto является использование его вместо многоуровневых break.

        Хуевый какой-то goto. Настоящие цари хотят иметь возможность перейти из середины одного трижды вложенного for в середину другого трижды вложенного for.
        Ответить
        • >Хуевый какой-то goto. Настоящие цари хотят иметь возможность перейти из середины одного трижды вложенного for в середину другого трижды вложенного for.

          Я специально процитирую незелёным.
          Ибо зачем goto, если никуда толком нельзя to go?
          Особенно майндфачные, мозголомные переходы внутрь хитросплетённых свитчей.

          >и обычным применением оператора goto является использование его вместо многоуровневых break.
          Пхп во всей красе.
          Ответить
        • Настоящие цари знают что в ISA x86 вообще ничего нету кроме jumpов (кондишенал и анкондишенал) так что вообще ничего кроме goto им не нужно.

          Правда там был какой-то loop (со счетчиком в CX кажется)
          Ответить
          • >Правда там был какой-то loop (со счетчиком в CX кажется)
            ЕМНИП loop очень медленный

            Потому всё в порядке: Настоящие Цари никогда не опустятся до использования такой гнусной комманды, просаживающей пирфоманс.
            Ответить
            • цари знают просто в какое количество микроопов на какой архитектуре мапица какая комманда:)

              Кстати, копеляторы вроде не используют loop. или используют?
              Ответить
              • >цари знают просто в какое количество микроопов на какой архитектуре мапица какая комманда:)
                Конечно знают. anger fog в помощь

                loop on various microarchitectures, from Agner Fog's instruction tables:
                
                    K8/K10: 7 m-ops
                
                    Bulldozer-family/Ryzen: 1 m-op (same cost as macro-fused test-and-branch, or jecxz)
                
                    P4: 4 uops (same as jecxz)
                    P6 (PII/PIII): 8 uops
                    Pentium M, Core2: 11 uops
                    Nehalem: 6 uops. (11 for loope / loopne)
                    SnB-family: 7 uops. (11 for loope / loopne). Only 2 uops for jecxz
                    Silvermont: 7 uops
                    AMD Jaguar (low-power): 8 uops, 5c throughput
                    Via Nano3000: 2 uops


                >Кстати, копеляторы вроде не используют loop. или используют?
                Нет, его не используют эдак с 486 процов


                LOOP became slow on some of the earliest machines (circa 486) when significant pipelining started to happen.
                And running any but the simplest instruction down the pipeline efficiently was technologically impractical. 
                So LOOP was slow for a number of generations. So nobody used it. 
                So when it became possible to speed it up, there was no real incentive to do so, since nobody was actually using it.

                Ответить
                • >>anger fog в помощь
                  Интересно, как он это померил? Интел давал утилиту или доки?

                  про loop понятно, но не понятен аргумент про преимущество simplest ops в pipeline. Все равно же они перемалываются в microops. Тем более что современные ISA имеют неебически сложные команды, всякие SIMD итд.
                  Ответить
                  • >Интел давал утилиту или доки?
                    Ха-ха.

                    >Интересно, как он это померил?
                    У него на сайте набор самописных тулзов с исходниками.
                    Ответить
                    • ого
                      гвозди-бы делать из таких людей:) Правда, это все будет менятся с каждой новой архитектурой же

                      Ну интел как-то давал утилиту чтобы измерять cache miss, так что иногда и там бывают просветления.
                      Ответить
                      • >это все будет менятся с каждой новой архитектурой же

                        Ну когда ryzen вышел он довольно быстро обновил свой pdf.
                        Ответить
                        • ничо си он активный
                          а Касперси его еще в 2003 году назвал устаревшим

                          А он мало того что жив, да еще и за AMD следит
                          Ответить
                          • Йа там недавно на местном хардварном форуме даже Линуса видывал. Тоже читает-с.
                            Ответить
                            • Кстать, в одной игре я встречал пасхалку виде Линуса. Только он жил в палатке в лесу в порваной одежде и постоянно говорил что занят.
                              Ответить
          • Есть еще CMOVcc
            Ответить

    Добавить комментарий