На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: JoeUser, Qraizer, Hsilgos
Страницы: (77) « Первая ... 73 74 [75] 76 77   ( Перейти к последнему сообщению )  
> Текущий Стандарт С++ и перспективы его развития
    Интересно, по стандарту чему должно быть равно i в этом примере:
    ExpandedWrap disabled
      int i = 1;
      i = i++;
    Мой сайт - www.prografix.narod.ru
      По стандарту это ill-formed и UB. Ибо двойная модификация одной переменной в рамках одного же выражения.
      "Математики думают, что Бог в уравнениях, нейрологи уверены, что Бог в мозге, а программисты уверены, что Бог — один из них."
      Морган Фриман
      Реализация шаблонов Jinja2 для C++ Jinja2 C++
        Цитата prografix @
        Интересно, по стандарту чему должно быть равно i в этом примере:

        https://en.cppreference.com/w/cpp/language/eval_order

        Добавлено
        Цитата Flex Ferrum @
        По стандарту это ill-formed и UB.

        Так по старому же вроде стандарту UB, в новом точки следования убрали ведь? Или вернее заменили на что то другое.
          До сих пор не допилено в Стандарте, ИМХО. Особенно это "радует":

          ExpandedWrap disabled
            f(++i, ++i);       // undefined behavior until C++17, unspecified after C++17
          Мои программные ништякиhttp://majestio.info
            Ну а что не так - низзя так рисовать, низзя. Как ни назови.
            Windows as usual - my "wau" Windows experience
              А отчего нельзя то? Если i вначале было равно 2, то первый должен пойти параметр 3, второй - 4, а потом вызов. То, что в стэк аргументы наоборот кладутся - проблема компилятора, а не синтаксиса с семантикой.
                Цитата Славян @
                Если i вначале было равно 2, то первый должен пойти параметр 3, второй - 4, а потом вызов.
                С чего ты так решил? Написано же до C++17 это было undefined behavior, а начиная с C++17 - unspecified.
                То есть раньше компилятор мог в такой ситуации делать что бог на душу положит, причем каждый раз по-разному. Теперь он должен выбрать определённое поведение (не обязательно совпадающее с твоим мнением, и даже не обязательно разумное) и следовать ему. Он может передать пару значений 3, 4, как ты думаешь, или пару значений 4, 3, если вычисляет значения параметров в обратном порядке, или значения 3, 3, если имитирует параллельное вычисление аргументов, или значения 4 и 4, если сперва выполняет оба инкремента. Более того он может заносить в стек любые два значения на выбор разработчиков.
                Всё написанное выше это всего лишь моё мнение, возможно ошибочное.
                  Да начхать же как сейчас работает компилятор! Код же написан, понимается человеком весьма просто и прямо: вызвать f, у коей первый аргумент 2++ (то бишь 3), а потом снова переменная++ (то бишь 4). Всё абсолютно чётко. Нет никаких параллельных вычислений!! Как записано, так пусть и считает! :angry:
                    Цитата Славян @
                    Всё абсолютно чётко. Нет никаких параллельных вычислений!! Как записано, так пусть и считает! :angry:

                    Точек следования нет + работа ведется с одной и той же областью памяти. Из за чего при оптимизации, могут возникнуть конфликты.
                    Для обеспечения скорости, компилятор может переупорядочивать выражения по своему усмотрению во время оптимизации программы, что приводит к тому, что у тебя даже код программы может выполнятся не в том порядке, в каком он написан тобою.
                    Предположим ты написал вот так:
                    ExpandedWrap disabled
                      int i = 2;
                      f(++i, ++i);       // undefined behavior until C++17, unspecified after C++17

                    И ожидаешь внутри функции получить первый аргумент равным - 3, и второй аргумент равным - 4.
                    Но так как в этом выражении нет точек следования, компилятор в праве переупорядочить по своему усмотрению данную инструкцию, и ты можешь получить что то типа того:
                    ExpandedWrap disabled
                      f(i=4, i=3)

                    Или например вообще вот такое:
                    ExpandedWrap disabled
                      f(i+1, i+1)
                      {
                         i += 2;
                      }

                    Или еще что то другое.
                      Вот второе - не должно быть. Ибо префиксный оператор должен отработать до входа в функцию.
                      А с первым - да, печально.
                      Мои программные ништякиhttp://majestio.info
                        Цитата JoeUser @
                        Вот второе - не должно быть. Ибо префиксный оператор должен отработать до входа в функцию.

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

                        Добавлено
                        Цитата JoeUser @
                        Ибо префиксный оператор должен отработать до входа в функцию.

                        А если учесть именно вот это, то вообще можно получить вот такой результат:
                        ExpandedWrap disabled
                              int i = 2;
                              f(++i, ++i);       // undefined behavior until C++17, unspecified after C++17
                              {
                                param1 = 4;
                                param2 = 4;
                              }

                        Т.е. внутри функции оба аргумента будут равны 4. Мы ведь инкрементировали одну и ту же переменную, результат посчитался до тела функции. Как результат - Славян ожидает 3, 4, а на деле имеет 4, 4 - что более логично.
                          Цитата Wound @
                          а деле имеет 4, 4 - что более логично.

                          По идее - да!
                          Сперва инкремент, и только потом передача параметров.
                          Мои программные ништякиhttp://majestio.info
                            Цитата Wound @
                            Точек следования нет + работа ведется с одной и той же областью памяти. Из за чего при оптимизации, могут возникнуть конфликты.
                            А) Годьте! Если только на этапе оптимизации, то это проблема недоделанного оптимизатора. Пусть осторожней работает! Если же не только, то давайте смотреть этот обыденный случай.
                            Б) Я не шибко улавливаю фразу "точка следования" (только путём общелогических умозаключений), так что расскажите попроще на этом простом примере, что тут не так? Всё же просто: вызов с двумя аргументами, кои записаны подряд, а значит и вычисляться должны подряд! Так что f(3,4);

                            Цитата Wound @
                            Для обеспечения скорости, компилятор может переупорядочивать выражения по своему усмотрению во время оптимизации программы, что приводит к тому, что у тебя даже код программы может выполнятся не в том порядке, в каком он написан тобою.
                            Ещё раз напомню, что шаманство компилятора при оптимизации - его изъян; пусть хуже оптимизирует, но не допускает ошибок/двузначностей.
                              Цитата Славян @
                              Я не шибко улавливаю фразу "точка следования" (только путём общелогических умозаключений)

                              Читать тут.
                              Мои программные ништякиhttp://majestio.info
                                Это:
                                Цитата
                                Порядок вычисления операндов любого C++ оператора, включая порядок вычисления аргументов функции в выражении вызова функции, и порядок вычисления вложенных выражений внутри любого выражения, не определён
                                звучит как "считайте, как захочется". Чуть ли не аксиоматически=законодательно. Бред какой-то. Зачем так сделали?
                                Впрочем, тема обсуждения явно рвётся в холиварчики. :blush:

                                Добавлено
                                А-а-а-а! Дочитал ниже, и всё становится понятно! Школота малограмотная пишет же! Так надо:
                                Цитата
                                Точка следования, это точка последовательности выполнения, в которой все побочные эффекты от вычислений, стоящих раньше в последовательности, завершены, и никакие побочные эффекты, относящиеся к последующим вычислениям, не начали выполняться.
                                :facepalm: :facepalm: :facepalm:
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (77) « Первая ... 73 74 [75] 76 77 


                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1930 ]   [ 15 queries used ]   [ Generated: 18.09.18, 15:35 GMT ]