На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
  
> Чистота кода VS оптимизация
    Много статей развелось про чистоту кода (на основе книги Р.Мартина и не только). В целом концепция, конечно, хорошая.
    Но бывают какие-то прямо абсурдные, ИМХО, рекомендации.
    Вот к примеру тут:
    ExpandedWrap disabled
      // ????
      const fetchData = (id) => {
        if (id) {
          fetch('/data/' + id)
        }
      }
      // ????
      const fetchData = (id) => {
        if (!id) {
          return
        }
        fetch('/data/' + id)
      }
    Ну что это за "красота" такая?

    И вот такие слова в конце статьи:
    Цитата
    «Погодите! А как насчет изменения производительности?». Мне это безразлично. Правда. Разве что есть реальная проблема, когда приложение становится медленнее, чем ожидалось.

    С таким мышлением закон Вирта совершенно не кажется "шуткой":
    Цитата
    Программы становятся медленнее куда шустрее, чем компьютеры становятся быстрее

    Далее, второй момент. Более "тонкий", скажем так.
    Example1 (кусочек кода):
    ExpandedWrap disabled
      . . .
        while i*i <= n:
          k = 1
          while n % i == 0:
            k += 2
            n //= i
          result /= k
          i += 1
      . . .

    Example2 (кусочек кода):
    ExpandedWrap disabled
      . . .
        while i*i <= n:
          if n % i == 0:
            k = 3
            while 1:
              n //= i
              if n % i: break
              k += 2
            result /= k
          i += 1
      . . .
    Не углубляйтесь в суть алгоритма, это неважно.
    Второй вариант чуть более сложный для понимания (спасибо разработчикам Python'а за отсутствие do-while/repeat-until), но и чуть более оптимальный по скорости, ибо тут нет лишнего деления (ну и кое-чего ещё по мелочи).
    Согласен, не самый показательный пример (особенно учитывая, что это скриптовый язык, но давайте не будем обращать на это внимания, вникните в суть темы... представьте, что это C++ :)).

    Собственно, можно особо не заморачиваться и использовать первый вариант. Но представим, что мы пишем библиотеку и не знаем как она будет использоваться. Насколько критична будет скорость в финальном коде?

    Ваши мысли обо всём этом безобразии... :whistle:
      Не читай плохих статей! :lol: Создавать Elephantware имеет смысл только тогда, когда ты в пожизненной разработке проекта, и тебе оплачивают не качество, а количество доработок.
        Цитата Jin X @
        Не углубляйтесь в суть алгоритма, это неважно.

        как это не углубляйтесь? возможно там вообще деление не нужно
          Цитата villain @
          как это не углубляйтесь? возможно там вообще деление не нужно
          Суть вообще не в этом. Будем считать, что алгоритм достаточно оптимален (это часть кода разложения на простые множители и манипуляции с ними), но есть 2 вот таких варианта реализации :)
          Там вообще умножение должно быть, я заменил его на деление для пущего эффекта :D
            Цитата JoeUser @
            Создавать Elephantware имеет смысл только тогда, когда ты в пожизненной разработке проекта, и тебе оплачивают не качество, а количество доработок.
            Не, ну понятно, что создавать класс в 3 поколения с 10 методами в каждом там, когда нужно сделать просто min(x,y) - это бред. Речь идёт именно о чистоте кода, а не о заделе на будущее. Т.е. о понятности кода тебе и людям с возможностью лёгкой модификации.
            Реально ли (почти) всегда нужно писать одно действие-одна функция и выстраивать 5-этажные вызовы там, где можно было бы обойтись одной функцией?
            Реально ли (почти) всегда стоит заменять:
            ExpandedWrap disabled
              // ????
              people
                .filter(person => person.age > 10 && person.firstName.length > 2 && person.lastName.length > 4)
            на:
            ExpandedWrap disabled
              // ????
              people
                .filter(person => person.age > 10)
                .filter(person => person.firstName.length > 2)
                .filter(person => person.lastName.length > 4)
            ради лучшей читабельности? И т.д.
              Цитата Jin X @
              Реально ли (почти) всегда стоит заменять:
              ExpandedWrap disabled
                // ????
                people
                  .filter(person => person.age > 10 && person.firstName.length > 2 && person.lastName.length > 4)
              на:
              ExpandedWrap disabled
                // ????
                people
                  .filter(person => person.age > 10)
                  .filter(person => person.firstName.length > 2)
                  .filter(person => person.lastName.length > 4)
              ради лучшей читабельности? И т.д.

              Можно еще вот так
              ExpandedWrap disabled
                // ????
                people.filter(
                  person =>
                    person.age > 10 &&
                    person.firstName.length > 2 &&
                    person.lastName.length > 4
                )
              Сообщение отредактировано: applegame -
                Цитата Jin X @
                Ну что это за "красота" такая?

                Думаю, что тут имелся в виду принцип о размещении реакции на нарушения предусловий и обработки "внешних" ошибок в начале функций/методов.
                Как правило это действительно улучшает читаемость, поскольку дальнейшеая логика становится более простой.

                Добавлено
                Цитата Jin X @
                И вот такие слова в конце статьи:
                Цитата
                «Погодите! А как насчет изменения производительности?». Мне это безразлично. Правда. Разве что есть реальная проблема, когда приложение становится медленнее, чем ожидалось.

                С таким мышлением закон Вирта совершенно не кажется "шуткой":
                Цитата
                Программы становятся медленнее куда шустрее, чем компьютеры становятся быстрее

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

                Добавлено
                Цитата Jin X @
                Но представим, что мы пишем библиотеку и не знаем как она будет использоваться.

                Совсем не знаем? Тогда зачем пишем? :D

                Добавлено
                Цитата Jin X @
                Реально ли (почти) всегда стоит заменять:
                ExpandedWrap disabled
                  // ????
                  people
                    .filter(person => person.age > 10 && person.firstName.length > 2 && person.lastName.length > 4)
                на:
                ExpandedWrap disabled
                  // ????
                  people
                    .filter(person => person.age > 10)
                    .filter(person => person.firstName.length > 2)
                    .filter(person => person.lastName.length > 4)
                ради лучшей читабельности? И т.д.

                А здесь лучше читабельность? :D
                  Цитата Jin X @
                  Второй вариант чуть более сложный для понимания (спасибо разработчикам Python'а за отсутствие do-while/repeat-until), но и чуть более оптимальный по скорости
                  Какой же он оптимальный? Тут в каждом цикле два деления, когда можно обойтись одним.
                    Цитата amk @
                    Тут в каждом цикле два деления
                    2 деления во внешне цикле, 2 во внутреннем. Во втором примере при невыполнении условия внешнего цикла деление одно (в самом этом условии).
                    Цитата amk @
                    когда можно обойтись одним.
                    Мне вот даже интересно, как тут можно обойтись одним делением? :)

                    Добавлено
                    А, ну вот вижу вроде в питоне есть функция divmod, но это для внешнего цикла только... а дальше?

                    Добавлено
                    Хотя нифига, divmod, как оказалось, работает медленнее (даже медленнее 2 вызовов: % и //)

                    Добавлено
                    Причём, я сейчас замерил скорость Example1 и Example2 (причём, с умножением, а не с делением result'а). Разница более 30%, о как!
                      Цитата Jin X @
                      Хотя нифига, divmod, как оказалось, работает медленнее (даже медленнее 2 вызовов: % и //)
                      Т ак ты же вроде просил не обращать внимания на язык. В Си оптимизатор заменяет пару % / на одно деление. Вынесение одной из этих двух операций может сломать оптимизацию.

                      В любом случае нет смысла огород городить из-за всего одного сэкономленного деления. Судя по всему, это деление мало на что влияет.
                        Цитата D_KEY @
                        Совсем не знаем? Тогда зачем пишем?
                        Вот написал кто-то функцию power. Сразу понятно, где она может использоваться? :)

                        Добавлено
                        Цитата amk @
                        Т ак ты же вроде просил не обращать внимания на язык.
                        :lol:
                        Ну код же не на Си :)
                        Но в любом случае % во внутреннем цикле и result /= k ты одним делением не сделаешь.

                        Добавлено
                        Но мы от сути вопроса отошли...
                          Цитата Jin X @
                          Цитата D_KEY @
                          Совсем не знаем? Тогда зачем пишем?
                          Вот написал кто-то функцию power. Сразу понятно, где она может использоваться? :)

                          Да, практически везде, где будет применим сам язык. Значит это будет где-то в стандартной библиотеке и должно работать приемлемо во всех нишах, на которые рассчитан язык :)
                            Цитата Jin X @
                            parseOne('code_1','js',false)preloadCodeButtons('1');Ну что это за "красота" такая?

                            Тут видимо конфликт рекомендаций. Должно быть
                            ExpandedWrap disabled
                              const fetchData = (id) => {
                                if (!id)  return;
                                fetch('/data/' + id)
                              }


                            Но это противоречит безопасности if без else. Да и return по серёдке кода.

                            ExpandedWrap disabled
                              . . .
                                while i*i <= n:
                                  if n % i == 0:
                                    k = 3
                                    while 1:
                                      n //= i
                                      if n % i: break
                                      k += 2
                                    result /= k
                                  i += 1
                              . . .

                            Цитата Jin X @
                            Второй вариант чуть более сложный для понимания (спасибо разработчикам Python'а за отсутствие do-while/repeat-until),

                            Так там другой подход через множества.
                            Данный код лишён контекста(окружения) поэтому сказать как его от рефакторить трудно. Но как минимум он напрашивается на разбиение на 2 функции. Скорее всего эти 2 функции можно нормально поименовать, внутрь вставить ваши оптимизации. А для того что-бы вызов функций не тормозил сделать их через шаблоны.

                            Цитата Jin X @
                            Собственно, можно особо не заморачиваться и использовать первый вариант. Но представим, что мы пишем библиотеку и не знаем как она будет использоваться. Насколько критична будет скорость в финальном коде?

                            Это смотря как писать. Вот к примеру есть математическая библиотека eigen легко читаемая оптимизированная и не уступает по скорости конкурентам.
                            Или взять agg тоже качественный код. На самом деле я у себя сформировал комплект исходных кодов, которые счёл наиболее качественными.

                            Цитата Jin X @
                            Ваши мысли обо всём этом безобразии...

                            Считаю что надо стараться писать как можно более понятный код. Почему стараться? Потому что те библиотеки, которые я назвал появились не на пустом месте до них были другие библиотеки, которые имели плохой код. Во-вторых надо писать только то что нужно не делать код на будущее. Код развивается и постепенно наполняет новыми функциями но в тоже время код подлежит рефакторенгу. Тот же OpenCV переживает уже 4 версию. Каждая версия не совместима с другой потому что отрефакторина убран плохой код убраны подпорки.
                            Правда OpenCV не дотягивает до качественного кода, так как содержит нечитаемый код. В этом плане AForge.NET мне больше нравится (Си#),
                              Цитата Jin X @
                              Ну что это за "красота" такая?

                              Очевидно, что второй вариант на порядок лучше, хз что тебе не нравится :-?

                              Добавлено
                              Цитата Pavia @
                              Тут видимо конфликт рекомендаций. Должно быть

                              Фигурные скобки опускать никогда нельзя :yes:
                                Цитата Serafim @
                                Фигурные скобки опускать никогда нельзя
                                Никогда не говори "никогда". :yes:
                                  Цитата Serafim @
                                  Очевидно, что второй вариант на порядок лучше
                                  Он лучше, когда основной код занимает больше 1 строки, а здесь какой смысл в этом нагромождении?

                                  Цитата Pavia @
                                  Но это противоречит безопасности if без else.
                                  Как же делать if, в котором не нужен else? Прописывать else; тоже не фонтан...
                                    Цитата Jin X @
                                    Цитата Serafim @
                                    Очевидно, что второй вариант на порядок лучше
                                    Он лучше, когда основной код занимает больше 1 строки, а здесь какой смысл в этом нагромождении?

                                    Сейчас там 1 строка, завтра может быть 10. Без "нагромождения" нужно будет переписывать.
                                    pull-request'ы будут больше и дольше будешь апрувов ждать :D
                                    Сообщение отредактировано: D_KEY -
                                      Цитата Jin X @
                                      Он лучше, когда основной код занимает больше 1 строки, а здесь какой смысл в этом нагромождении?

                                      Ранний выход из функции проще читается. Я хз как сформулировать своими словами почему именно проще, ты меня в тупик поставил :-?
                                        D_KEY, намекаешь на то, что все будут пытаться исправить?

                                        Serafim, я понимаю, когда там хотя бы 2-3 строки основного кода. Или если есть большая вероятность, что код будет дописан. Но если предпосылок к расширению кода пока особых нет, чем это лучше?
                                        ExpandedWrap disabled
                                          const fetchData = (id) => {
                                            if (!id) return;
                                            fetch('/data/' + id)
                                          }
                                        против
                                        ExpandedWrap disabled
                                          const fetchData = (id) => {
                                            if (id) fetch('/data/' + id)
                                          }

                                        Хоть со {скобками}, хоть без... :)
                                          Цитата Jin X @
                                          Цитата villain @
                                          как это не углубляйтесь? возможно там вообще деление не нужно
                                          Суть вообще не в этом. Будем считать, что алгоритм достаточно оптимален (это часть кода разложения на простые множители и манипуляции с ними), но есть 2 вот таких варианта реализации :)
                                          Там вообще умножение должно быть, я заменил его на деление для пущего эффекта :D

                                          :facepalm:
                                          это не 2 варианта реализации, это 2 разных алгоритма
                                          первый лучше - нет внезапного выхода из цикла, 2 условия vs 4
                                          а за
                                          ExpandedWrap disabled
                                            while 1:
                                               ...
                                               if n % i: break

                                          отдельный котёл положен >:(
                                            Цитата villain @
                                            это не 2 варианта реализации, это 2 разных алгоритма
                                            По большому счёту, это один алгоритм всё же. Вот, к примеру здесь тоже 3 разных алгоритма?

                                            Цитата villain @
                                            а за
                                            ...
                                            отдельный котёл положен
                                            Это отсутствие do-while в Python. Можно поменять 2 последние строки местами, как вариант, а перед циклом написать k=1 :)
                                              Цитата Jin X @
                                              По большому счёту, это один алгоритм всё же. Вот, к примеру здесь тоже 3 разных алгоритма?

                                              порядок действий разный? значит разные.

                                              Цитата Jin X @
                                              Это отсутствие do-while в Python. Можно поменять 2 последние строки местами, как вариант, а перед циклом написать k=1 :)

                                              зачем, если есть вариант без этих костылей?
                                                Цитата Jin X @
                                                Serafim, я понимаю, когда там хотя бы 2-3 строки основного кода. Или если есть большая вероятность, что код будет дописан. Но если предпосылок к расширению кода пока особых нет, чем это лучше?

                                                Как минимум тем, что в первом варианте явно видна сигнатура Promise|null, а во втором - нет.

                                                Да и, повторюсь, за опускание фигурных скобок хочется убивать :D В культурном мире - это как код без отступов - признак плохих манер или неуча за клавиатурой. По крайней мере в JS и некоторых других языках, где уже давно есть codestyle стандарты.
                                                  Цитата Serafim @
                                                  Да и, повторюсь, за опускание фигурных скобок хочется убивать :D В культурном мире - это как код без отступов - признак плохих манер или неуча за клавиатурой.

                                                  Ох уж мне эти "культурные люди", все-то они возводят в абсолют :)
                                                  ExpandedWrap disabled
                                                    void doSmthng(){
                                                    if(smthngBad1)throw new Exception("Something bad 1");
                                                    if(smthngBad2)throw new Exception("Something bad 2");
                                                    if(smthngBad3)throw new Exception("Something bad 3");
                                                     
                                                    do();
                                                    }

                                                  Появление фигурных скобок читаемость ухудшит в разы.
                                                  Сообщение отредактировано: Астарот -
                                                    Цитата Астарот @
                                                    Появление фигурных скобок читаемость ухудшит в разы.

                                                    Ага, конечно
                                                    ExpandedWrap disabled
                                                      function doSmthng() {
                                                          switch (true) {
                                                              case smthngBad1:
                                                                  throw new Exception("Something bad 1");
                                                              case smthngBad2:
                                                                  throw new Exception("Something bad 1");
                                                              case smthngBad3:
                                                                  throw new Exception("Something bad 1");
                                                          }
                                                       
                                                          do();
                                                      }


                                                    Добавлено
                                                    И то, это потому, что в JS нет нормального паттерн матчинга
                                                      Цитата Serafim @

                                                      Ага, конечно

                                                      И зачем ты три легко читаемые строчки превратил в... это? :D Да и речь шла про
                                                      Цитата Serafim @
                                                      за опускание фигурных скобок хочется убивать

                                                      Ну, вот случай, когда опускать их прямо показано :thanks:
                                                        Цитата Serafim @
                                                        Ага, конечно
                                                        ExpandedWrap disabled
                                                          function doSmthng() {
                                                              switch (true) {
                                                                  case smthngBad1:
                                                                      throw new Exception("Something bad 1");
                                                                  case smthngBad2:
                                                                      throw new Exception("Something bad 1");
                                                                  case smthngBad3:
                                                                      throw new Exception("Something bad 1");
                                                              }
                                                           
                                                              do();
                                                          }

                                                        Вот за такое и правда, хочется взять и у@#$ть. Мне понадобилось несколько секунд, чтобы понять что за муйня такая этот ваш switch(true).
                                                        Сообщение отредактировано: applegame -
                                                          Цитата applegame @
                                                          Вот за такое и правда, хочется взять и у@#$ть.

                                                          Редкий случай, но я вот тут соглашусь :yes:
                                                            Цитата Serafim @
                                                            И то, это потому, что в JS нет нормального паттерн матчинга
                                                            И чем тебе в этом случае поможет "нормальный" паттерн-матчинг?
                                                            Сообщение отредактировано: applegame -
                                                              Цитата applegame @
                                                              И чем тебе в этом случае поможет "нормальный" паттерн-матчинг?

                                                              Думаю речь тут идет в том числе о том, что в js в case можно методы вызывать, то есть за исключением многословности тот же if получается.
                                                                Цитата Serafim @
                                                                Ага, конечно
                                                                ExpandedWrap disabled
                                                                  function doSmthng() {
                                                                      switch (true) {
                                                                          case smthngBad1:
                                                                              throw new Exception("Something bad 1");
                                                                          case smthngBad2:
                                                                              throw new Exception("Something bad 1");
                                                                          case smthngBad3:
                                                                              throw new Exception("Something bad 1");
                                                                      }
                                                                   
                                                                      do();
                                                                  }
                                                                И как вы, Serafim, переделаете Астаротский пример, если будет обработка с возвратом?.. (или в Яве такого нет?)
                                                                  Цитата applegame @
                                                                  И чем тебе в этом случае поможет "нормальный" паттерн-матчинг?

                                                                  хороший вопрос) в данном случае, кажется, ничем)

                                                                  Цитата Славян @
                                                                  И как вы, Serafim, переделаете Астаротский пример, если будет обработка с возвратом?.. (или в Яве такого нет?)

                                                                  Имеется ввиду посткондишн? Для этого приватные методы и декораторы, кажется, придумали)
                                                                    При чем тут приватные методы и декораторы ? О_о
                                                                      Цитата Астарот @
                                                                      При чем тут приватные методы и декораторы ? О_о

                                                                      1) Крупные методы принято делить на более мелкие, в частности твой вариант, в языках с возвращаемым значением в операндах (JS, Python, Ruby), вместо кастуемых (Java, PHP) моет выглядеть следующим образом:

                                                                      ExpandedWrap disabled
                                                                        // На псевдокоде, а-ля JS или жаба
                                                                        class Some {
                                                                            public function doSmthng() {
                                                                                return checkAbility(a) && checkAbility(b) && checkAbility(c) && do(); // В первой группе языков вернётся значение последнего метода
                                                                            }
                                                                         
                                                                            private function checkAbility(value) {
                                                                                return (bool)value || throw new Exception('...');
                                                                            }
                                                                        }


                                                                      а ещё можно воспользоваться редукцией в группе "вторых языков" :)

                                                                      ExpandedWrap disabled
                                                                        private function checkAbilities(...values): bool {
                                                                            return values.reduce((i, result) -> result ? !i : result, true); // Возвращает, либо тру, либо фолс, если один из аргументов values его содержит
                                                                        }



                                                                      2) В случае если нужна "обработка с возвратом", что бы это не значило, то можно воспользоваться декоратором, и завраппить ответ. Например, из твоего опыта Астарот, могу привести в пример NotNull аннотацию, которая "враппит" (или контейнеризирует, или декорирует, или вообще это монада :D ) оригинальное значение. Не она, конечно, а подписчик, не допуская нулевого значения в содержимом. В тоже время Ensure и Verify контракты DbC вполне могут сойти за одну из частных применений декораторов на методах. Выбирай любой способ.

                                                                      Добавлено
                                                                      P.S. Но это всё имеет смысл, когда подобных операций больше трёх. В примере из трёх булевых достаточно:
                                                                      ExpandedWrap disabled
                                                                        function doSmthng() {
                                                                            if (smthngBad1 || smthngBad2 || smthngBad3) {
                                                                                throw new Exception("Something bad");
                                                                            }
                                                                         
                                                                            do();
                                                                        }
                                                                      Сообщение отредактировано: Serafim -
                                                                        Цитата Serafim @
                                                                        моет выглядеть следующим образом

                                                                        Какой кошмар :-? Однострочник, в котором еще найди нужную do(), или наоборот нужную проверку, которую ты вынес на сторону, и куда нужно еще посмотреть, что б узнать, что именно оно бросает. Бряки на дебаге тоже ставить одно удовольствие. Б-же, зачем себя так не любить?

                                                                        Цитата Serafim @
                                                                        а ещё можно

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

                                                                        Добавлено
                                                                        Цитата Serafim @
                                                                        В примере из трёх булевых

                                                                        Ага, а потом гадай - какая же из трех "выстрелила" :D
                                                                          Цитата Астарот @
                                                                          Убивайтунг! Вот просто и сразу - ну, не читается же глазом эта билеберда, так зачем? Потому что можешь? Наверное, никогда не пойму этого...
                                                                          Сильно похоже на ЫГМ - Ынтырпрайз Гойловного Моска.
                                                                            Цитата Астарот @
                                                                            то есть за исключением многословности тот же if получается.

                                                                            Что интересно, в любом случае получится if-else, только на несколько уровней ниже.
                                                                              Цитата applegame @
                                                                              Сильно похоже на ЫГМ - Ынтырпрайз Гойловного Моска.

                                                                              Не знаю, что это, но мне реально страшно - это ж что он может навертеть в действительно не очевидных местах! :unsure:
                                                                                Цитата Астарот @
                                                                                Не знаю, что это, но мне реально страшно - это ж что он может навертеть в действительно не очевидных местах! :unsure:
                                                                                Вот что это такое - FizzBuzz Enterprise Edition is a no-nonsense implementation of FizzBuzz made by serious businessmen for serious business purposes.
                                                                                Вот где настоящий ужас :lol:
                                                                                Сообщение отредактировано: applegame -
                                                                                  Не понимаю, что тебе не нравиться, там даже тесты есть :D
                                                                                    Цитата Астарот @
                                                                                    Не понимаю, что тебе не нравиться, там даже тесты есть :D
                                                                                    Что значит "даже"? >:(
                                                                                    Это коммерческий код написанный коммерческим программистом в соответствии с высочайшими энтерпрайз стандартами. Там по определению не может не быть тестов.
                                                                                      switch(true) - это сильно :)
                                                                                      Больше похоже на обфускацию, а не упрощение кода :lol:

                                                                                      Цитата Serafim @
                                                                                      моет выглядеть следующим образом
                                                                                      Это прикольный выкрутас, конечно (и где-то даже "классический"). Вот только если попадёт в руки джуну, не каждый сообразит, как сие работает.
                                                                                      Цитата Serafim @
                                                                                      а ещё можно воспользоваться редукцией в группе "вторых языков"
                                                                                      А вот это особенно.

                                                                                      Добавлено
                                                                                      Цитата Астарот @
                                                                                      Ага, а потом гадай - какая же из трех "выстрелила"

                                                                                      ExpandedWrap disabled
                                                                                        function doSmthng() {
                                                                                            var i;
                                                                                            if (smthngBad1 && (i=1) || smthngBad2 && (i=2) || smthngBad3 && (i=3)) {
                                                                                                throw new Exception("Something bad " + i);
                                                                                            }
                                                                                         
                                                                                            doIt();
                                                                                        }
                                                                                      Или...
                                                                                      ExpandedWrap disabled
                                                                                        function doSmthng() {
                                                                                            var i = 1;
                                                                                            if (smthngBad1 || ++i && smthngBad2 || ++i && smthngBad3) {
                                                                                                throw new Exception("Something bad " + i);
                                                                                            }
                                                                                         
                                                                                            doIt();
                                                                                        }
                                                                                      :lol:
                                                                                        А что это switch(true) делает? Я верно понял, что switch разворачивается в пачку if-ов, в каждом из которых проверяется равенство того, что в switch и в case?
                                                                                          OpenGL, получается так...
                                                                                          ExpandedWrap disabled
                                                                                            if (true == smthngBad1) {...}
                                                                                            if (true == smthngBad2) {...}
                                                                                          Сообщение отредактировано: Jin X -
                                                                                            Цитата Jin X @
                                                                                            if (smthngBad1 && (i=1) || smthngBad2 && (i=2) || smthngBad3 && (i=3)) {

                                                                                            И потом нарываешься на хитро закопанные грабли в виде смены ключей оптимизации кода, и выясняется... (памяти {$B+})
                                                                                              Цитата Vesper @
                                                                                              И потом нарываешься на хитро закопанные грабли в виде смены ключей оптимизации кода, и выясняется

                                                                                              А причём тут оптимизация? && и || обязаны выполняться по-порядку, и оптимизатор не имеет права их переставлять.
                                                                                                Vesper, ну это ж не Delphi, там бы {$B-} был. Ну и это отчасти троллинг примера Серафима, а отчасти... ну мне тоже нравятся такие конструкции и нагромождения всякие (усложнения) :)
                                                                                                А && имеет более высокий приоритет, чем ||.

                                                                                                Добавлено
                                                                                                Есть ещё замечательная операция xor (^).
                                                                                                Тоже можно побаловаться а-ля if (x ^ y) doSmthng();
                                                                                                Видимо, ^^ не стали делать как раз от греха подальше :D

                                                                                                Добавлено
                                                                                                Serafim, вот скажи. Ну нафига фигурные скобки для if (while, for... нужное подчеркнуть), который прописан в одну строку?
                                                                                                Собственно, это смежно с if (id) fetch('/data/' + id);
                                                                                                  Цитата Jin X @
                                                                                                  Больше похоже на обфускацию, а не упрощение кода

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

                                                                                                  С другой стороны, мне кажется нормальным использование switch/case для однотипных условных операторов. Кажется, что для этого он и был предназначен, не?)
                                                                                                    Я понимаю, что какой-нибудь ландырь может по запаре забыть поставить скобки, но при наличии выравнивания этот косяк сразу будет виден...

                                                                                                    Добавлено
                                                                                                    Эх, не успел склеить с предыдущим сообщением <_<

                                                                                                    Добавлено
                                                                                                    Цитата Serafim @
                                                                                                    Кажется, что для этого он и был предназначен, не?)
                                                                                                    ИМХО, он был (хорошее слово) предназначен для проверки 1 переменной на разные значения, а не наоборот :)
                                                                                                      Цитата Jin X @
                                                                                                      Serafim, вот скажи. Ну нафига фигурные скобки для if (while, for... нужное подчеркнуть), который прописан в одну строку?

                                                                                                      Для языков, которые я использую - это общепринятый стандарт, всё равно потом CS поправит код в CI, так что пофигу.

                                                                                                      Да и вообще, ГОСТ для C/C++, кажется, есть на эту тему :whistle:
                                                                                                        Цитата Serafim @
                                                                                                        Но это всё имеет смысл, когда подобных операций больше трёх.
                                                                                                        Когда больше трёх, ИМХО, лучше использовать не отдельные переменные, а множество, к примеру...
                                                                                                          Цитата Jin X @
                                                                                                          ИМХО, он был (хорошее слово) предназначен для проверки 1 переменной на разные значения, а не наоборот

                                                                                                          Допускаю, что ты прав. Но это не значит, что обратный случай - плохой.
                                                                                                            Цитата Serafim @
                                                                                                            ГОСТ
                                                                                                            СНиП и СанПиН :)
                                                                                                              Цитата Jin X @
                                                                                                              Когда больше трёх, ИМХО, лучше использовать не отдельные переменные, а множество, к примеру...

                                                                                                              +1
                                                                                                                Serafim, кстати, что ты думаешь об if (smthngBad1 && (i=1) || smthngBad2 && (i=2) || smthngBad3 && (i=3)) ? :P
                                                                                                                  Цитата Jin X @
                                                                                                                  Видимо, ^^ не стали делать как раз от греха подальше

                                                                                                                  Не от греха подальше, а потому что операция бесмысленна. Главное отличие || от | (&& и &, соответственно), помимо того, что одна - логическая, а вторая - побитовая в том, что первая ещё и ленивая. А вот ^^ ленивой не сделать.

                                                                                                                  Цитата Jin X @
                                                                                                                  Vesper, ну это ж не Delphi, там бы {$B-} был.

                                                                                                                  Хм, прочитал про это. Какому идиоту вздумалось вводить этот ключ? :unsure: Это же трындец какой-то.
                                                                                                                    Цитата Jin X @
                                                                                                                    Serafim, кстати, что ты думаешь об if (smthngBad1 && (i=1) || smthngBad2 && (i=2) || smthngBad3 && (i=3)) ?

                                                                                                                    Это печально :) Сам иногда говнокодю, делая присваивания в условиях, но не до такой степени :D
                                                                                                                      Цитата Serafim @
                                                                                                                      Сам иногда говнокодю, делая присваивания в условиях, но не до такой степени :D

                                                                                                                      Эй, а он не безнадежен! :D
                                                                                                                        Цитата OpenGL @
                                                                                                                        А причём тут оптимизация? && и || обязаны выполняться по-порядку, и оптимизатор не имеет права их переставлять.
                                                                                                                        При этом они ещё точки следования вставляют, так что ++ в безопасности.
                                                                                                                        Цитата Jin X @
                                                                                                                        Видимо, ^^ не стали делать как раз от греха подальше
                                                                                                                        Это обычное !=. Зачем?
                                                                                                                          Цитата OpenGL @
                                                                                                                          Не от греха подальше, а потому что операция бесмысленна. Главное отличие || от | (&& и &, соответственно), помимо того, что одна - логическая, а вторая - побитовая в том, что первая ещё и ленивая. А вот ^^ ленивой не сделать.
                                                                                                                          Если под ленивой ты подразумеваешь проверку одного условия из 2-х (если оно true для ||), то отчего ж && не ленивая (при первом false)?

                                                                                                                          Цитата Qraizer @
                                                                                                                          Это обычное !=. Зачем?
                                                                                                                          Точно. Тормознул чё-т я :facepalm: :) (see below)

                                                                                                                          Цитата Serafim @
                                                                                                                          но не до такой степени
                                                                                                                          Ну ладно... if (smthngBad1 || ++i && smthngBad2 || ++i && smthngBad3)
                                                                                                                          Как будто бы и не присвоение почти :D
                                                                                                                          (на всякий случай скажу, что согласен, что это говнокодинг, но выглядит прикольно, поэтому иногда так и подмывает так писать)

                                                                                                                          Добавлено
                                                                                                                          Цитата Qraizer @
                                                                                                                          Это обычное !=. Зачем?
                                                                                                                          Цитата Jin X @
                                                                                                                          Точно. Тормознул чё-т я
                                                                                                                          Хотя нет, не тормознул...
                                                                                                                          5 != 7 = true
                                                                                                                          но
                                                                                                                          5 ^^ 7 = false

                                                                                                                          Добавлено
                                                                                                                          Если только так извращаться:
                                                                                                                          ExpandedWrap disabled
                                                                                                                            var x=5, y=7;
                                                                                                                            alert((x&&1) != (y&&1));  // false
                                                                                                                          но это бред.
                                                                                                                          Сообщение отредактировано: Jin X -
                                                                                                                            Цитата Jin X @
                                                                                                                            Если под ленивой ты подразумеваешь проверку одного условия из 2-х (если оно true для ||), то отчего ж && не ленивая (при первом false)?

                                                                                                                            && тоже ленивая уж. Имеется ввиду, что || в моём предложении ты можешь заменить на &&, а | на &.
                                                                                                                              Вот, блин!
                                                                                                                              В JS:
                                                                                                                              5&&1 = 1, а 1&&5 = 5
                                                                                                                              5||0 = 5 и 0||5 = 5 (почему одинаково - понятно, но почему не true/false?)
                                                                                                                              Чё за бред? :wall:

                                                                                                                              p.s. В сях всё нормально работает: везде выдаёт 1 или true (в т.ч. для 2&&1 и 1&&~1, что ожидаемо).

                                                                                                                              Добавлено
                                                                                                                              Цитата OpenGL @
                                                                                                                              Имеется ввиду, что || в моём предложении ты можешь заменить на &&, а | на &.
                                                                                                                              Что??? :blink:

                                                                                                                              Добавлено
                                                                                                                              OpenGL, ты имеешь в виду, что && и || ленивые в отличие от & и | ?
                                                                                                                              А разве основная ценность в этой ленивости? И это достаточная причина, чтобы не делать ^^ ?
                                                                                                                              Ну реально бывает (редко, но бывает), что нужно сделать (x ^^ y). Можно, конечно, написать (!x != !y), но это тоже не вот прям офигеть как читаемо :)
                                                                                                                              Сообщение отредактировано: Jin X -
                                                                                                                                Цитата Jin X @
                                                                                                                                Хотя нет, не тормознул...
                                                                                                                                Ну это не серьёзно. Типы данных разные, и && и &, равно как и || и |, определены для разных типов, для которых есть взаимные касты, тогда как != одна на все типы, и кастов не требуется. Ты же не думаешь, что за типами следить не надо? А то я как-то видал в коде if(a != true), было весело писать багрепорты.
                                                                                                                                  Цитата Qraizer @
                                                                                                                                  Ты же не думаешь, что за типами следить не надо?
                                                                                                                                  Надо, но всегда ли есть смысл писать if (x != 0), когда можно написать просто if (x) ?
                                                                                                                                  А в случае с xor как-то тоже бредово выглядит if ((x && !y) || (!x && y)) и аналогично if ((x!=0 && y==0) || (x==0 && y!=0)).
                                                                                                                                  Как ты предлагаешь реализовать xor, чтобы получилось красиво?

                                                                                                                                  Добавлено
                                                                                                                                  Цитата Jin X @
                                                                                                                                  тоже бредово выглядит
                                                                                                                                  Или:
                                                                                                                                  ExpandedWrap disabled
                                                                                                                                    bool boolX = x, boolY = y;
                                                                                                                                    if (boolX != boolY) {...}
                                                                                                                                  тоже не айс...

                                                                                                                                  if ((bool)x != (bool)y) :no:

                                                                                                                                  Добавлено
                                                                                                                                  В JS соответственно:
                                                                                                                                  ExpandedWrap disabled
                                                                                                                                    var boolX=!!x, boolY=!!y;
                                                                                                                                    if (boolX != boolY) {...}
                                                                                                                                  Сообщение отредактировано: Jin X -
                                                                                                                                    Цитата Jin X @
                                                                                                                                    OpenGL, ты имеешь в виду, что && и || ленивые в отличие от & и | ?

                                                                                                                                    Да.

                                                                                                                                    Добавлено
                                                                                                                                    Цитата Jin X @
                                                                                                                                    А разве основная ценность в этой ленивости? И это достаточная причина, чтобы не делать ^^ ?

                                                                                                                                    Имхо, да. Из-за ленивости ты сможешь написать что-то наподобие if(index < a.len() && a[index] < 42), и замена && на & тут не прокатит. ^^ же ровно с тем же успехом в большинстве случаев заменяется на ^.

                                                                                                                                    Цитата Jin X @
                                                                                                                                    Ну реально бывает (редко, но бывает), что нужно сделать (x ^^ y).

                                                                                                                                    Когда x и y не булевские, и просто конвертятся неявным кастом? Я в этом случае просто сам сравниваю с нулём. Т.е. как-то if ((x != 0) ^ (y != 0)) пишу.
                                                                                                                                      Периодически встречаются конструкции вида if x % 1 == 0 или if not 1 % 1 — проверка на целое (python)
                                                                                                                                      Или n = ~~(n/5) — деление нацело (JS)
                                                                                                                                      Прикольно, конечно, но в "чистоте" такого кода у меня сомнения...
                                                                                                                                        Цитата Jin X @
                                                                                                                                        Надо, но всегда ли есть смысл писать if (x != 0), когда можно написать просто if (x) ?

                                                                                                                                        Почему нет? В языках без неявного приведения к bool писать != 0 не напрягает совершенно.
                                                                                                                                          Цитата Jin X @
                                                                                                                                          Вот, блин!
                                                                                                                                          В JS:
                                                                                                                                          5&&1 = 1, а 1&&5 = 5
                                                                                                                                          5||0 = 5 и 0||5 = 5 (почему одинаково - понятно, но почему не true/false?)
                                                                                                                                          Чё за бред?

                                                                                                                                          Я же написал даже, что есть языки, где операнды возвращают значение, а не булев результат: Чистота кода VS оптимизация (сообщение #3766081) пункт номер 1 ;)
                                                                                                                                            Цитата OpenGL @
                                                                                                                                            Т.е. как-то if ((x != 0) ^ (y != 0)) пишу.
                                                                                                                                            Вариант, конечно (тогда можно использовать != – так понятнее).
                                                                                                                                            Но это точно лучше, чем if (x ^^ y) (если бы он был)?

                                                                                                                                            Добавлено
                                                                                                                                            Цитата Serafim @
                                                                                                                                            Я же написал даже, что есть языки, где операнды возвращают значение, а не булев результат
                                                                                                                                            Сенькс. В Java так же?
                                                                                                                                              Цитата Jin X @
                                                                                                                                              Это точно лучше, чем if (x ^^ y) (если бы он был)?

                                                                                                                                              Зависит от того, как ты относишься к неявным кастам чисел к bool :-? Я вот за пределами олимпиад стараюсь их избегать, и поэтому даже if (a && b) у меня выглядит как if (a != 0 && b != 0)
                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                  #define XOR(a, b) (bool(a) != bool(b))
                                                                                                                                                  . . .
                                                                                                                                                  if (XOR(x, y)) {...}
                                                                                                                                                :P
                                                                                                                                                Сообщение отредактировано: Jin X -
                                                                                                                                                  Цитата Jin X @
                                                                                                                                                  Сенькс. В Java так же?

                                                                                                                                                  Я не помню, кажется там каст к булеву. Тут тебе Астарот поможет.

                                                                                                                                                  А в Ruby и JS - 146% возврат значения. Плюс, в рубях и котлине сами операторы могут возвращать значение, типа:
                                                                                                                                                  ExpandedWrap disabled
                                                                                                                                                    return if (errValue || errValue2) {
                                                                                                                                                      throw Exception("Whoops!")
                                                                                                                                                    } else {
                                                                                                                                                      print("OK")
                                                                                                                                                      do();
                                                                                                                                                      true
                                                                                                                                                    }
                                                                                                                                                  Сообщение отредактировано: Serafim -
                                                                                                                                                    Цитата Serafim @
                                                                                                                                                    Плюс, в рубях и котлине сами операторы могут возвращать значение
                                                                                                                                                    C++
                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                      int func(int val)
                                                                                                                                                      {
                                                                                                                                                        return val ? (printf("%d ", val), 2) : -1;
                                                                                                                                                      }
                                                                                                                                                       
                                                                                                                                                      int main()
                                                                                                                                                      {
                                                                                                                                                        int x;
                                                                                                                                                        scanf("%d", &x);
                                                                                                                                                        printf("%d\n", func(x));
                                                                                                                                                        return 0;
                                                                                                                                                      }


                                                                                                                                                    Добавлено
                                                                                                                                                    Или так :)
                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                      int func(int val)
                                                                                                                                                      {
                                                                                                                                                        return val ? ({int x = val*5; printf("%d ", x); 2;}) : -1;
                                                                                                                                                      }
                                                                                                                                                       
                                                                                                                                                      int main()
                                                                                                                                                      {
                                                                                                                                                        int x;
                                                                                                                                                        scanf("%d", &x);
                                                                                                                                                        printf("%d\n", func(x));
                                                                                                                                                        return 0;
                                                                                                                                                      }
                                                                                                                                                      ммм. А как тема "Чистота кода VS оптимизация" превратилась в соревнование кто по-уродливее код написать может? :unsure:
                                                                                                                                                        Это значит, что любой оператор (хотя в котлине вроде только if):
                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                          verifyItems = (...args) => (i or throw Error "asd" for i of args).length


                                                                                                                                                        Применение для каждого элемента args функции, которая в случае элемента, который равен false вернёт ошибку, в остальных случаях значение аккумулируется и от него берётся length, т.е. количество элементов в результате (этот ваш незамысловатый i++ в if условии).

                                                                                                                                                        А вот даже можно собрать это всё
                                                                                                                                                          Цитата Jin X @
                                                                                                                                                          Как ты предлагаешь реализовать xor, чтобы получилось красиво?
                                                                                                                                                          ExpandedWrap disabled
                                                                                                                                                            if(!!x != !!y) /* ... */
                                                                                                                                                          :D
                                                                                                                                                            Qraizer, ага. С одним ! не так красиво? :)
                                                                                                                                                              Конечно, нет. Алгоритм-то другой.
                                                                                                                                                                А я, Serafim, вообще стараюсь избегать фигурных, если позволительно, a'la:
                                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                                  if( ... )
                                                                                                                                                                    A = B,
                                                                                                                                                                    func1( ... ),
                                                                                                                                                                    p = func2(...);
                                                                                                                                                                  else
                                                                                                                                                                    C = D, ...;
                                                                                                                                                                :blush:
                                                                                                                                                                  Славян, ну это уже борщ, ИМХО :whistle:
                                                                                                                                                                    Цитата Славян @
                                                                                                                                                                    А я, Serafim, вообще стараюсь избегать фигурных, если позволительно, a'la:

                                                                                                                                                                    А я джунов своих по рукам за это бью)
                                                                                                                                                                      Бедные джуны.
                                                                                                                                                                        Цитата Serafim @
                                                                                                                                                                        Цитата Славян @
                                                                                                                                                                        А я, Serafim, вообще стараюсь избегать фигурных, если позволительно, a'la:

                                                                                                                                                                        А я джунов своих по рукам за это бью)

                                                                                                                                                                        А тот код, что ты выше приводил, заставляешь писать? :lol:
                                                                                                                                                                          Зато QA меньше проблем с "внезапно появившимися багами из ниоткуда" ;)

                                                                                                                                                                          Добавлено
                                                                                                                                                                          Цитата D_KEY @
                                                                                                                                                                          А тот код, что ты выше приводил, заставляешь писать?

                                                                                                                                                                          Допустим повышенный Complexity, как в примере выше, обычный анализатор сам подсветит, сложнее с Protected Variations и Cohesion - тут надо самому думать как не свалиться в рефакторинг)
                                                                                                                                                                            Цитата Jin X @
                                                                                                                                                                            А && имеет более высокий приоритет, чем ||.

                                                                                                                                                                            Приоритет приоритетом, но флаг complete boolean eval означает вычислить все части булева выражения, даже если они уже не влияют на итоговый результат. Пример был вида "if (a<100) or add1(a) then..." где add1 - функция с сайд-эффектом, возвращающая boolean, и при B+ переменная а всегда увеличивалась, а при В- только если (а<100) было ложным. Вот мало ли кто захочет зачем-то поменять эту нас ройку, тем боле если в заголовке где-то проскочит, а особенно если это что-то фиг-отладишь типа буста. Вот надо им было, а ты теперь страдай.
                                                                                                                                                                            Цитата OpenGL @
                                                                                                                                                                            Хм, прочитал про это. Какому идиоту вздумалось вводить этот ключ? Это же трындец какой-то.

                                                                                                                                                                            Сюрприз, да :D
                                                                                                                                                                              Цитата Vesper @
                                                                                                                                                                              Приоритет приоритетом, но флаг complete boolean eval означает вычислить все части булева выражения, даже если они уже не влияют на итоговый результат.
                                                                                                                                                                              Цитата Vesper @
                                                                                                                                                                              Сюрприз, да
                                                                                                                                                                              Ну вообще, по умолчанию она отключена. Но я, например, если пишу код, в котором эта настройка (или какая-либо другая) важна, прописываю её в заголовке и проблем нет.
                                                                                                                                                                              Там помимо этой настройки есть ещё R, Q, Z и пр., которые тоже могут неслабо влиять на результат.
                                                                                                                                                                              Надо просто знать об этом и проставлять нужные опции. В IDE есть комбинация Ctrl+O+O, которая позволяет быстро увидеть текущие настройки и зафиксировать их.

                                                                                                                                                                              Добавлено
                                                                                                                                                                              В целом же, довольно неплохо иметь привычку всовывать в начало исходников строчку вида {$A8,Z1,O+,Q-,R-,B-}
                                                                                                                                                                              А в главный модуль (program) можно ещё и {$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED} (при подключенном модуле Windows, ну или {$SetPEFlags 1}) вставлять для удаления фиксапов из EXE-шника (которые там нафиг не нужны). Только в DLL такого не надо делать :)
                                                                                                                                                                                Неужели кто-то ещё пишет на Delphi?
                                                                                                                                                                                  D_KEY, нет, конечно, никто не пишет.
                                                                                                                                                                                  Embarcadero чисто по загону новые версии выпускает. Для прикола, тупо поржать ;)
                                                                                                                                                                                    Цитата Jin X @
                                                                                                                                                                                    ...(которые там нафиг не нужны)
                                                                                                                                                                                    ...чем напрочь запрещаем ASLR.
                                                                                                                                                                                    Сообщение отредактировано: Qraizer -
                                                                                                                                                                                      Цитата Vesper @
                                                                                                                                                                                      Вот мало ли кто захочет зачем-то поменять эту нас ройку, тем боле если в заголовке где-то проскочит, а особенно если это что-то фиг-отладишь типа буста.

                                                                                                                                                                                      В плюсовых компиляторах тоже такая настройка имеется? Что-то сильно сомневаюсь. Максимум, что ты сделаешь в плюсах - перегрузишь логические операторы для своих типов. И вообще, можно пруф того, что это бывает не только в дельфи?
                                                                                                                                                                                        Цитата Qraizer @
                                                                                                                                                                                        чем напрочь запрещаем ASLR.
                                                                                                                                                                                        Чтобы ASLR работал, нужно либо включить соответствующие опции в PE-заголовке (при компиляции, например). Либо прописать эти опции в реестре для конкретного файла.
                                                                                                                                                                                        Но в целом ты прав, конечно.

                                                                                                                                                                                        Добавлено
                                                                                                                                                                                        Не углублялся в эту тему раньше.
                                                                                                                                                                                        Ну тогда вместо отключения фиксапов можно включать ASLR и DEP (ну или просто DEP хотя бы):
                                                                                                                                                                                        ExpandedWrap disabled
                                                                                                                                                                                          {$APPTYPE CONSOLE}
                                                                                                                                                                                          uses Windows, SysUtils;
                                                                                                                                                                                          const
                                                                                                                                                                                            IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = $40;  // ASLR, {$DYNAMICBASE ON} in Delphi 2007+
                                                                                                                                                                                            IMAGE_DLLCHARACTERISTICS_NX_COMPAT = $100;    // DEP
                                                                                                                                                                                          {$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE or IMAGE_DLLCHARACTERISTICS_NX_COMPAT} // {$SetPEOptFlags $140}, works on Delphi 6+ (and maybe earlier)
                                                                                                                                                                                          // http://qaru.site/questions/663368/how-can-i-enable-depnx-and-aslr-on-a-delphi-2006-or-earlier-executable
                                                                                                                                                                                          // https://habrahabr.ru/company/eset/blog/206244/
                                                                                                                                                                                           
                                                                                                                                                                                          const R: Byte = $C3;
                                                                                                                                                                                          begin
                                                                                                                                                                                            WriteLn(IntToHex(DWord(@IntToHex), 8));
                                                                                                                                                                                            try
                                                                                                                                                                                              TProcedure(@R);
                                                                                                                                                                                              WriteLn('DEP is OFF :(');
                                                                                                                                                                                            except
                                                                                                                                                                                              WriteLn('DEP is ON :)');
                                                                                                                                                                                            end;
                                                                                                                                                                                          end.
                                                                                                                                                                                        Сообщение отредактировано: Jin X -
                                                                                                                                                                                          Без reloc-ов по-любому ASLR не заработает. Но тут как бы палка о двух концах. Во время отладки стрипать их даже полезно, ибо бряки, не привязанные к строкам кода, а поставленные, скажем, на конкретные ассемблерные инструкции, что нередко бывает нужно для либ без сыров, при активном ASLR слетают токатак. Но вот в релизе я удалять их всё-таки бы не советовал.
                                                                                                                                                                                            Цитата Qraizer @
                                                                                                                                                                                            Без reloc-ов по-любому ASLR не заработает.
                                                                                                                                                                                            Да это понятное дело.

                                                                                                                                                                                            Цитата Qraizer @
                                                                                                                                                                                            Во время отладки стрипать их даже полезно
                                                                                                                                                                                            Можно так:
                                                                                                                                                                                            ExpandedWrap disabled
                                                                                                                                                                                              {$IFDEF DEBUG}
                                                                                                                                                                                                {$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED}
                                                                                                                                                                                              {$ELSE}
                                                                                                                                                                                                {$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE}
                                                                                                                                                                                              {$ENDIF}
                                                                                                                                                                                              {$SetPEOptFlags IMAGE_DLLCHARACTERISTICS_NX_COMPAT}
                                                                                                                                                                                            :)
                                                                                                                                                                                              Кстати, кто подскажет, что это за прога (которая показывает заголовок PE в таком виде)?

                                                                                                                                                                                              user posted image

                                                                                                                                                                                              user posted image
                                                                                                                                                                                                Цитата Serafim @
                                                                                                                                                                                                Крупные методы принято делить на более мелкие, в частности твой вариант, в языках с возвращаемым значением в операндах (JS, Python, Ruby), вместо кастуемых (Java, PHP) моет выглядеть следующим образом:



                                                                                                                                                                                                А в нормальных следующим:

                                                                                                                                                                                                ExpandedWrap disabled
                                                                                                                                                                                                  doSomethingClever :: Int -> String -> String
                                                                                                                                                                                                  doSomethingClever id name = show id ++ " => " ++ name
                                                                                                                                                                                                   
                                                                                                                                                                                                  tryToDoSomethingClever :: Maybe Int -> Result String
                                                                                                                                                                                                  tryToDoSomethingClever idParam = do
                                                                                                                                                                                                      id   <- getId idParam
                                                                                                                                                                                                      item <- getItem id
                                                                                                                                                                                                      name <- getName item
                                                                                                                                                                                                      return (doSomethingClever id name)


                                                                                                                                                                                                Добавлено
                                                                                                                                                                                                Цитата Jin X @
                                                                                                                                                                                                Embarcadero чисто по загону новые версии выпускает. Для прикола, тупо порубить хоть чуть-чуть бабла на легаси-проектах

                                                                                                                                                                                                Ага.
                                                                                                                                                                                                Сообщение отредактировано: korvin -
                                                                                                                                                                                                  Цитата korvin @
                                                                                                                                                                                                  А в нормальных следующим:

                                                                                                                                                                                                  Оуоу, палехче)))

                                                                                                                                                                                                  P.S. А это разве не первый вариант? Возвращается же в конце концов функция (точнее композиция функций). Только указанная в качестве первого операнда, если, конечно не использовался оператор "$", тогда вернётся последующий аргумент.

                                                                                                                                                                                                  P.P.S. Хотя... Кажется это ещё один вариант:

                                                                                                                                                                                                  1) C, Java, PHP: "res = a || b"
                                                                                                                                                                                                  Результат: res = bool

                                                                                                                                                                                                  2) JS, Ruby, Python: "res = a || b"
                                                                                                                                                                                                  Результат: res = a (если он тру) или b

                                                                                                                                                                                                  3) Haskell: "res = a || b"
                                                                                                                                                                                                  Результат: функция "||" от a и b (я довольно плохо плохо знаю Haskell, так что поправь, если ошибаюсь)
                                                                                                                                                                                                  Сообщение отредактировано: Serafim -
                                                                                                                                                                                                    Цитата Serafim @
                                                                                                                                                                                                    Результат: функция "||" от a и b

                                                                                                                                                                                                    Что?

                                                                                                                                                                                                    ExpandedWrap disabled
                                                                                                                                                                                                      {-
                                                                                                                                                                                                       
                                                                                                                                                                                                      tryToDoSomethingClever :: Maybe Int -> Result String
                                                                                                                                                                                                      tryToDoSomethingClever idParam = do
                                                                                                                                                                                                          id   <- getId idParam
                                                                                                                                                                                                          item <- getItem id
                                                                                                                                                                                                          name <- getName item
                                                                                                                                                                                                          return (doSomethingClever id name)
                                                                                                                                                                                                       
                                                                                                                                                                                                      tryToDoSomethingClever :: Maybe Int -> Result String
                                                                                                                                                                                                      tryToDoSomethingClever idParam =
                                                                                                                                                                                                          getId idParam >>= (\id ->
                                                                                                                                                                                                              getItem id >>= (\item ->
                                                                                                                                                                                                                  getName item >>= (\name ->
                                                                                                                                                                                                                      return (doSomethingClever id name))))
                                                                                                                                                                                                       
                                                                                                                                                                                                      -}
                                                                                                                                                                                                       
                                                                                                                                                                                                      tryToDoSomethingClever :: Maybe Int -> Result String
                                                                                                                                                                                                      tryToDoSomethingClever idParam =
                                                                                                                                                                                                          case getId idParam of
                                                                                                                                                                                                              Err msg -> Err msg
                                                                                                                                                                                                              Ok  id  -> case getItem id of
                                                                                                                                                                                                                  Err msg  -> Err msg
                                                                                                                                                                                                                  Ok  item -> case getName item of
                                                                                                                                                                                                                      Err msg  -> Err msg
                                                                                                                                                                                                                      Ok  name -> Ok (doSomethingClever id name)


                                                                                                                                                                                                    https://ideone.com/f4Bzen
                                                                                                                                                                                                    Сообщение отредактировано: korvin -
                                                                                                                                                                                                      Цитата Serafim @
                                                                                                                                                                                                      1) C, Java, PHP: "res = a || b"
                                                                                                                                                                                                      Результат: res = bool
                                                                                                                                                                                                      Что значит bool? true если a, иначе true если b, иначе false. При проверке условия вместо возврата результата сразу производится переход к нужной ветке.
                                                                                                                                                                                                      На самом деле вычисление результата тоже производится переходами.
                                                                                                                                                                                                      То есть фактически в C res = a || b означает res = (a || b)? true: false

                                                                                                                                                                                                      Цитата Serafim @
                                                                                                                                                                                                      2) JS, Ruby, Python: "res = a || b"
                                                                                                                                                                                                      Результат: res = a (если он тру) или b
                                                                                                                                                                                                      В Python надо писать res = a or b. В остальном почти верно. При вычислении результата, сразу после определения значения выражения производится переход на точку сохранения результата.
                                                                                                                                                                                                        Цитата amk @
                                                                                                                                                                                                        Что значит bool?

                                                                                                                                                                                                        Это означает, что там может находиться либо true, либо false и никак иначе.
                                                                                                                                                                                                          Цитата Serafim @
                                                                                                                                                                                                          Это означает, что там может находиться либо true, либо false и никак иначе.
                                                                                                                                                                                                          Но не указано, что если по `a` можно определить ответ, то `b` не анализируется
                                                                                                                                                                                                            amk, я думаю, это не сложно определить эмпирически :)
                                                                                                                                                                                                              Цитата amk @
                                                                                                                                                                                                              Но не указано, что если по `a` можно определить ответ, то `b` не анализируется

                                                                                                                                                                                                              Да ладно? :o Ты уверен? :huh:
                                                                                                                                                                                                                Уверен. В C это описано стандартом.
                                                                                                                                                                                                                Так же и в C++, если переменные не являются пользовательскими типами.
                                                                                                                                                                                                                Но в таком случае не может быть уверенности даже в результирующем значении. Пользовательский operator||() вовсе не обязан возвращать bool
                                                                                                                                                                                                                  Цитата Serafim @
                                                                                                                                                                                                                  Да ладно? Ты уверен?

                                                                                                                                                                                                                  Так практически везде же.
                                                                                                                                                                                                                    Простите, я табличку сарказма потерял :D
                                                                                                                                                                                                                    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                                                                                                                                                    0 пользователей:


                                                                                                                                                                                                                    Рейтинг@Mail.ru
                                                                                                                                                                                                                    [ Script execution time: 0,2262 ]   [ 16 queries used ]   [ Generated: 29.03.24, 15:54 GMT ]