1. C++ / Говнокод #9416

    +1013

    1. 1
    if (!done && (done = true)) setlocale(LC_CTYPE, "");

    из свежих ворнингов компилера.

    Запостил: Dummy00001, 14 Февраля 2012

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

    • проект все еще компилится. еще один привет (очевидно) от того же самого автора:

      if (first && !(first = false)) loadComponents();


      похоже у какого-то тима стратегические запасы фигурных скобок иссякли.
      Ответить
      • экономия ресурса клавиш Х и Ъ
        if (first) first = false, loadComponents();
        Ответить
        • у нас в большинстве тимов такое использование зяпятой было забанено благодаря чудаку который любил писать вот так:

          return Log->Warn("blablalbla"),-1;
          Ответить
      • Такой код по крайней мере будет работать, а в основной теме-то условие никогда не выполнится...
        Ответить
        • хороший вопрос.

          как по мне - неопределенность, потому что значение переменной в том же самом условии и проверяется и меняется.

          но по старым традициям С, условия проверяются/исполняются строго слева на право и останавливаются когда результат условия становится известен.

          поэтому оба условия работают: до присвоения исполнение не дойдет пока первая часть "&&" условия false.
          Ответить
          • > но по старым традициям С

            А можно пример языка, в котором порядок вычисления операндов "&&" неопределен?
            Ответить
            • уф... все чем я пользуюсь работает как надо. с одной стороны.

              с другой стороны. многие языки просто по семантике такое не позволяют. в С это работает за счет "side effects": у присвоения тоже есть результат. некоторые языки (например функциональные) стремятся искоренять эти побочные эффекты и просто исключают возможность смешивания присвоений и проверок. поэтому как бы проблемы в принципе и не существует.

              еще из классики жанра: MS Visual Basic. там как такого була нету и выражения всегда вычисляются полностью и результат проверяется на true-ness. хотя даже в VB я слышал спец операторы были введены что бы только часть выражения вычислялась, а не все целиком.
              Ответить
              • >хотя даже в VB я слышал спец операторы были введены что бы только часть выражения вычислялась, а не все целиком.
                Не слышал об таком.
                Все т.н. "спец-операторы" в версиях до .NET сводились к:
                замене
                if (cond1 and cond2) then
                на
                if (cond1) then
                if (cond2) then

                А всё оттого, что у MS VB был мудацкий компилятор.
                Ответить
                • специально для тебя гуглянул: смотри в AndAlso и OrElse операторы.
                  Ответить
                  • Ленивость
                    AndAlso -> &&
                    OrElse -> || ?
                    Ответить
                    • >AndAlso -> &&
                      >OrElse -> ||
                      Да. В VB.NET добавили много сишных и жавовских фич (try - catch for example) дабы сделать его максимально близким к шарпам.
                      Ответить
                  • >AndAlso and OrElse VB.NET Operators
                    >VB.NET Operators

                    >в версиях до .NET сводились к:
                    >до .NET

                    VB <> VB.NET
                    Ответить
            • В Erlang, на сколько я помню, не определен, т.как там нету ленивых вычислений (или только конструкторы списков ленивые...).
              Ответить
          • В C и С++ не запрета на проверку и изменение значения переменной "в одном и том же условии". В C и С++ есть запрет на проверку и изменение значения переменной без разделяющей их точки следования. Операторы '&&' и '||' в С и С++ создают точку следования, вследствие чего нарушения этого требования в данном случае нет. И нет никакой неопределенности.

            Порядок вычисления встроенных операторов '&&' и '||' (и свойство из "сокращенного вычисления") жестко закреплены стандартами этих языков, а не является какой-то произвольной данью "старым традициям".
            Ответить
            • спасибо за референс. самому в стандарт было лень лезть. плюсанул.

              "точка следования" это официальный перевод на русский?
              Ответить
              • Хм... Кто его знает, официальный он или нет. Я вот, например, других варинтов перевода никогда и не слышал. Вроде "точка следования" всегда говорили.
                Ответить
                • Точки следования - официально.

                  Только вот в C++11 их отменили.
                  Ответить
                  • Гонишь.

                    С++ в этих вещах ссылается на С, так как стандарты (с С++11 полностью) гармонизированы.

                    С стандарты - что С99 что С11 определяют sequence point'ы.
                    Ответить
                    • Номер пункта? В C++2003 был 1.9.7, в C++2011 его убрали.
                      Ответить
                      • по n3242 (final public draft).

                        во-первых. 1.1, #2 - генеральное заявление, что С++ не противоречит С где это не оговорено. норматив ISO для надстроек над существующими стандартами. переиспользуемые стандарты перечислеными в 1.2 - включая С99.

                        во-вторых. n2239, "A finer-grained alternative to sequence points" - они просто переименовали "sequence points" в "sequenced before". и blimey последние апдейты к С11 тоже переименовали это дело в С стандарте.
                        Ответить
                        • Вот именно. Sequence points отменили, вместо них ввели более соответствующие реалиям многопоточности и многопроцессорности понятия sequenced before, unsequenced, indeterminately sequenced, carries a dependency, dependency-ordered before, inter-thread happens before и т. п. Это даёт более чёткие гарантии и позволяет больше свободы оптимизатору.
                          Ответить
                          • > Sequence points отменили

                            не отменили - просто переименовали.

                            и расширили - т.к. многопотчность впервые попала официально в стандарт.

                            ну да называй как тебе это нравится. мне имена по барабану, если я знаю о чем ты говоришь ;)
                            Ответить
                            • Если б в тред зашел Тарас - он бы наверняка воскликнул КРЕСТОПРОБЛЕМЫ.
                              И был бы прав.
                              Ответить
                              • Да я заходил, долго думал, зачем так странно написано, потом промолчал и вышел.
                                Ответить
                        • Это - не верное утверждение. Замена секвенсинга через "точки следования" на секвенсинг через отношение "sequenced before" - это не просто переименование. Упорядочивание, задаваемое через "sequenced before" - существенно более слабое, чем упорядочивание, задаваемое через "точки следования".

                          Например, наличие точек следования автоматически подразумевает возможность partitioning-а, т.е. разделение всего множества событий на две четкие группы: одна группа происходит до точки следования другая - после (аналогично partitioning-у в алгоритме quicksort).

                          Идея же порядка, основанного на "sequenced before" (без каких либо дополнительных ограничений), задает лишь частичный порядок, который в общем случае не допускает однозначного partitioning-а.

                          Проблема точек следования как раз таки и заключалась во многом в том, что они превносили в язык чрезмерно жесткое требование partitioning-а. Во времена исключитально последовательного программирования это не мешало, но в современно программировании мы уже начали упираться в чрезмерную жесткость этого требования. Поэтому его и ослабили.

                          Это принципиальное изменение, а не какое-то "переименование".
                          Ответить
                          • Это может привести к тому, что старый код (код до С++11) станет вести себя не так, как задумывал автор?
                            Ответить
                            • Я имею ввиду код, написанный до принятия стандарта С++11, но компилируемый в С++11 компиляторе может перестать себя вести себя так, как было задумано программистом кода, написавшем его до принятия стандарта С++11, в котором ввели замену понятию sequence point?
                              Ответить
                              • Нет, не должно.
                                Ответить
                                • Обоснования есть?
                                  Ответить
                                  • В-первых, когда это все делалось, тщательнейшим образом старались не сломать старые программы.

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

                                    В-третих, формальное обоснование потребудет анализа пол-стандарта. Поля этого форума, так сказать, слишком узки... К тому же, я думаю, это уже было сделано. Читайте труды комитета.
                                    Ответить
                                    • сдался!

                                      теперь я думаю ты тоже готов назвать это "переименовали" и пойти заниматься чем-нибудь полезным.
                                      Ответить
                                    • >В-первых, когда это все делалось, тщательнейшим образом старались не сломать старые программы.
                                      Не заметил. Код старого стандарта не компилируется в новом:
                                      1)Старое auto перестало работать, хоть это и не страшно.
                                      2)Перекрывающие виртуальные методы во всех используемых библиотеках (в том числе и чужих) и во всем коде программы приходится помечать override или final иначе ошибка компиляции. А вот это уже очень напряжно.

                                      Какие несовместимости ещё забыл?
                                      Ответить
        • Это откуда такой вывод? При изначальном 'done == false' - прекрасно выполнится.
          Ответить
    • показать все, что скрытоif (!gone_done && (gone_done = true)) ffffuuu();
      Ответить
      • О. Привет, гумно! Таки залогинился? А то всё под гостем сидишь.
        Снова "итт-илитный" (ц) юмор?!

        А я тут для тебя картинку сделал. Вернее про тебя.
        http://rghost.ru/36535887
        Ответить
    • а как по мне - красиво
      Ответить

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