На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Постфиксный и префиксный инкремент , или декремент
    Привет всем!

    Бытует мнение, что использования префиксного инкремента или декремента (по-русски ++i --i) дает незначительную оптимизацию, по сравнению с постфиксным (по-русски i++ i--)

    Ваше мнение? Используете в своих проектах?

    P.S. я имею ввиду проекты, где очень важна скорость...
    Сообщение отредактировано: Russel -
      использую постфиксный ТОЛЬКО когда это необходимо.

      Цитата Russel @
      Бытует мнение, что использования префиксного инкремента или декремента (по-русски ++i --i) дает незначительную оптимизацию

      иногда, очень даже значительную оптимизацию.
        Если производится инкремент/декремент POD-типа, то пофигу. Если это перегруженный оператор, то всё зависит от его реализации. Обычно постфиксный ин(де)кремент реализуется через префиксный. А вообще, это несущественная мелочь, не в тех местах неэффективность ищешь. :)
          Цитата Relan @
          Если производится инкремент/декремент POD-типа, то пофигу. Если это перегруженный оператор, то всё зависит от его реализации.

          У некоторых POD-типов тоже могут быть перегруженные операторы. ;)
            Для перегруженных операторов ВСЕГДА быстрее префиксный
              Цитата arcsupport @
              Для перегруженных операторов ВСЕГДА быстрее префиксный

              :no: :no:
              в общем случае неверно.
              Но если говорить о перегруженных и стандартно себя ведущих операторах, то да, в огромном большинстве случаев постфиксный будет вести себя медленней.
                Цитата LuckLess @
                Но если говорить о перегруженных и стандартно себя ведущих операторах, то да, в огромном большинстве случаев постфиксный будет вести себя медленней


                Согласен. Ведь по логике вещей префиксный сразу прибавляет единицу и ненужну никакого левого кода. А ситуацию с постфиксным надо определять...
                  Цитата Relan @
                  А вообще, это несущественная мелочь, не в тех местах неэффективность ищешь. :)

                  Копейка рубль бережет...
                    Я компилирую все Интеловским компилятором, у меня разницы нет... скорее всего, он фиксит такие вещи и оптимизирует их по умолчанию...

                    Это наверно больше вопрос стиля, или предубеждений...

                    Есть у кого-нибудь еще мнения?

                    Добавлено
                    Да забыл сказать - чистый С (без классов)
                      Использую только префиксный вариант. Соглашусь с тем, что:
                      Цитата

                      А вообще, это несущественная мелочь, не в тех местах неэффективность ищешь.
                        Цитата Russel @
                        Это наверно больше вопрос стиля, или предубеждений...
                        Правильно реализованные перегруженные префиксные инкремент/декремент как правило не медленнее(если не быстрее) постфиксных. Т.к. последние требуют создания копии объекта, хранящей предыдущее значение.
                          Цитата Russel @
                          Да забыл сказать - чистый С (без классов)

                          ничего себе приписочка :D :D
                          Конечно,в Чистом С - пофигу, т.к. перегрузки операторов в нем нет :P
                            Цитата Relan @
                            Если производится инкремент/декремент POD-типа, то пофигу.

                            Разве для POD-типа постфиксный инкремент не должен создавать и возвращать временную переменную со старым значением? :huh:
                              Цитата Alex437 @
                              Разве для POD-типа постфиксный инкремент не должен создавать и возвращать временную переменную со старым значением? :huh:

                              int wah;
                              wah++; ... ну вернет int... и че?)) в любом случае меньше инта не вернеться...
                                Лично я использую постфиксный. С проектами где скорость крайне критична не работал, а вот глазу - проще ;)
                                  Цитата Мяут @
                                  а вот глазу - проще ;)

                                  ну этт на любителя..
                                  лично мне уже i++ в глазак ребит..)) сразу вижу.. и правлю, правлю :P
                                    Цитата LuckLess @
                                    int wah;
                                    wah++; ... ну вернет int... и че?))

                                    Да просто зачем создавать лишнюю переменную, которая никому не нужна? Получаются совершенно лишние действия. Тем более что их так просто избежать - всего лишь нарисовать плюсики спереди :D

                                    Цитата
                                    лично мне уже i++ в глазак ребит..)) сразу вижу.. и правлю, правлю

                                    :yes: аналогично
                                      Цитата Alex437 @
                                      Получаются совершенно лишние действия.

                                      Нету там никаких лишних действий (на нормальных компиляторах). Свободный i++ делает то же самое, что ++i.

                                      Цитата Alex437 @
                                      аналогично

                                      ExpandedWrap disabled
                                        m++;
                                        m*=n;

                                      ExpandedWrap disabled
                                        ++m;
                                        m*=n;

                                      Где лучше просматривается модификация m? В первом примере m везде находится слева, что легко замечается при беглом просмотре кода.
                                      Сообщение отредактировано: Unreal Man -
                                        Ребята, о вкусах не спорят.
                                        А что касается совместимости и удобства - лучше использовать префиксный
                                          Цитата Unreal Man @
                                          Свободный i++ делает то же самое, что ++i.

                                          Это потому что компилятор оптимизирует. А в языке C++ нет понятия "свободного инкремента" и "несвободного инкремента". И ничего не может зависеть от того, что он там свободный.
                                            Цитата
                                            Нету там никаких лишних действий. Свободный i++ делает то же самое, что ++i.

                                            результат здесь один и тотже, а действия разные в том числе и лишние. Надо четко разделять почему x = y[++i] и x = y[i++] дадут разные результаты. А отношение типа "а пофиг - это одно и тоже" это не аргумент, а источник ошибок

                                            Добавлено
                                            да, забыл - я за префикс...
                                              Unreal Man, ты лучше объясни какая разница между "свободным i++" и "несвободным i++"
                                                А разве не понятно? У свободного i++ значение оператора никем не используется.
                                                  Я имею в виду с точки зрения производительности.
                                                    Цитата Unreal Man @
                                                    Даже у меня на JavaScript не видно никакой разницы между свободными i++ и ++i :-) Хочешь писать программы под какой-то абстрактный компилятор C++ в надежде, что где-то ++i увеличит производительность – пиши на здоровье :-)

                                                    Постфиксный ++ практически всегда медленне для не ПОД типов.
                                                    Перед тем как это писать подумал бы..
                                                    компилятор не в праве оптимизировать постфиксный ++ префиксным, вне зависимости от того свободный он или нет для не POD типов.
                                                    И он не только не в праве, а он и не делает этого.

                                                    Добавлено
                                                    И причем тут втой ДжаваСкрипт вообще?
                                                      Цитата Unreal Man @
                                                      Хочешь писать программы под какой-то абстрактный компилятор C++ в надежде, что где-то ++i увеличит производительность – пиши на здоровье :-)

                                                      Я не под абстрактный компилятор пишу, я просто не люблю перекладывать на компилятор оптимизацию, которую вполне могу сделать сам.
                                                        Цитата Unreal Man @
                                                        Хочешь писать программы под какой-то абстрактный компилятор C++ в надежде, что где-то ++i увеличит производительность – пиши на здоровье
                                                        Лучше писать ++i зная, что какой-то компилятор C++ не уменьшит производительность ;) :D
                                                          Цитата Hryak @
                                                          У некоторых POD-типов тоже могут быть перегруженные операторы. ;)
                                                          Да, но речь-то о ++ и --. ;) Они ведь не могут быть перегружены (POD структуры не рассматриваем).
                                                          Цитата Russel @
                                                          Это наверно больше вопрос стиля, или предубеждений...
                                                          Я использую постфиксные для POD и префиксные для классов, включая итераторы (которые на самом деле могут быть указательями). Мне так проще.
                                                          Цитата Alex437 @
                                                          Разве для POD-типа постфиксный инкремент не должен создавать и возвращать временную переменную со старым значением? :huh:
                                                          Должен. Но если это значение имеет смысл, то тогда и спорить не о чем, т.к. использование того или иного опреатора определяется семантикой.
                                                          Цитата Alex437 @
                                                          Да просто зачем создавать лишнюю переменную, которая никому не нужна?
                                                          Господа, не надо считать оптимизатор дурачком. :) С такими семечками он расправляется без проблем.
                                                            Цитата Relan @
                                                            Да, но речь-то о ++ и --. ;) Они ведь не могут быть перегружены (POD структуры не рассматриваем).

                                                            Почемуйто ПОД структуры не рассматриваем??))

                                                            Вообще, если обобщить, то постфиксный практически 100% медленней префиксного для любого ползовательского оператора, по барабану ПОД тип или нет..
                                                              Цитата Relan @
                                                              Господа, не надо считать оптимизатор дурачком. :) С такими семечками он расправляется без проблем.

                                                              Про оптимизацию компилятором я уже писал в предыдущем посте. Я его дурачком не считаю, но и я тоже не дурачок :tong:
                                                                На оптимизатор надейся, а сам не плошай.
                                                                Префиксный инкремент где только возможно, постфиксный инкремент только при необходимости.
                                                                  Цитата Relan @
                                                                  Я использую постфиксные для POD и префиксные для классов
                                                                  ExpandedWrap disabled
                                                                    typedef что-то my_type;
                                                                    for( my_type i=0 ; i < 10 ; какой будешь использовать? );
                                                                  Сразу вопрос, а если потом поменяшь тип в typedef, будешь for переписывать?
                                                                    Цитата Alex437 @
                                                                    Я имею в виду с точки зрения производительности.

                                                                    Не пойму, к чему ты клонишь. Можно предположить, что свободному i++ незачем создавать копию (т.е. лишних действий делать не нужно).

                                                                    Цитата trainer @
                                                                    Лучше писать ++i зная, что какой-то компилятор C++ не уменьшит производительность

                                                                    Если всё идеализировать, то да. С практической же точки зрения это преимущество мизерно.

                                                                    P.S. Оффтоп (извиняюсь, но давно хотел сказать пару ласковых LuckLess и чтоб в присутствии других :-) )
                                                                    Цитата LuckLess @
                                                                    Постфиксный ++ практически всегда медленне для не ПОД типов.
                                                                    Перед тем как это писать подумал бы..

                                                                    А к чему я, по-твоему, пишу i? Это обычное имя для целочисленного счётчика. При чём тут не-POD типы? Ты вообще о чём? :-) Открой свои глазки и проследи за ходом дискуссии.

                                                                    Цитата LuckLess @
                                                                    И он не только не в праве, а он и не делает этого.

                                                                    О, сбасибо, что просветил! :-) Где ты увидел хотя бы намёк на то, что речь идёт о пользовательских типах? Ёжику понятно, что в отношении польз. типов нужно смотреть на конкретную реализацию инкрементов.

                                                                    Цитата LuckLess @
                                                                    И причем тут втой ДжаваСкрипт вообще?

                                                                    При том, что тут нету никакого компилятора, а разницы всё равно не видно никакой. На размышления не наводит?

                                                                    Далее. Твои игры с рейтингами – это вообще детсад :-) Наверно, никто на форуме не печётся о них больше, чем ты. И это при том, что ты сам бегом и вприпрыжку несёшься отвечать во все темы, порой уверенно выдавая за факты свои непродуманные домыслы (которые не всегда оказываются верными). Если бы я ставил тебе по минусу за каждый твой неудачный перл, у тебя бы уже с десяток твоих любимых очков поубавилось. Хочешь, я этим займусь? :-)
                                                                    Сообщение отредактировано: Unreal Man -
                                                                      Unreal Man
                                                                      Уфф..
                                                                      ты навернякак пришел в С++ из асма..

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

                                                                      ExpandedWrap disabled
                                                                           int j1 = ++i1;
                                                                        00412279  mov         eax,dword ptr [i1]
                                                                        0041227C  add         eax,1
                                                                        0041227F  mov         dword ptr [i1],eax
                                                                        00412282  mov         ecx,dword ptr [i1]
                                                                        00412285  mov         dword ptr [j1],ecx
                                                                           int i2;
                                                                           int j2 = i2++;
                                                                        00412288  mov         eax,dword ptr [i2]
                                                                        0041228B  mov         dword ptr [j2],eax
                                                                        0041228E  mov         ecx,dword ptr [i2]
                                                                        00412291  add         ecx,1
                                                                        00412294  mov         dword ptr [i2],ecx


                                                                      отчличий никаких(в плане производительности.
                                                                      Другое дело что
                                                                      1) Это уже было написано раньше, и если сказать это 3 раза -- лучше не станет.
                                                                      2) Всегда лучше придерживаться одного стиля. Поэтому всегда надо использовать префиксный(только если ты прям очень не привык к постфиксному).
                                                                      3) Джава скрипт вообще никакого отношения к делу не имеет.

                                                                      по поводу остального - думай обо мне что угодно, мне от этого ни теплей, ни холодней.
                                                                        Цитата Unreal Man @
                                                                        Не пойму, к чему ты клонишь. Можно предположить, что свободному i++ незачем создавать копию (т.е. лишних действий делать не нужно).

                                                                        Я тебе еще раз говорю, что нет никакого "свободного постфиксного инкремента" и "несвободного постфиксного инкремента" (если не веришь - загляни в стандарт :D ).
                                                                        Есть просто постфиксный инкремент и работает он везде одинаково, он просто по определению должен возвращать временную переменную (пока компилятор не сомптимизирует).
                                                                        Сообщение отредактировано: Alex437 -
                                                                          Цитата LuckLess @
                                                                          ты навернякак пришел в С++ из асма..

                                                                          Не угадал – из Delphi (но это снова оффтоп)

                                                                          Цитата LuckLess @
                                                                          отчличий никаких(в плане производительности.

                                                                          Может, мой тест был кривой, но с посфиксным++ аналогичная работа шла процентов на 20 быстрее :-)

                                                                          Цитата LuckLess @
                                                                          2) Всегда лучше придерживаться одного стиля.

                                                                          Можно использовать постфиксный инкремент для элементарных типов и префиксный для пользовательских. Тем самым это различие (с каким объектом идёт работа) будет наглядно подчёркиваться. Чем плох такой стиль?

                                                                          Цитата LuckLess @
                                                                          3) Джава скрипт вообще никакого отношения к делу не имеет.

                                                                          Ну если тебя это успокоит, то пускай будет так :-)

                                                                          Цитата Alex437 @
                                                                          Я тебе еще раз говорю, что нет никакого "свободного постфиксного инкремента"

                                                                          Не надо мне это объяснять – я всё прекрасно понимаю :-) Пожалуй, мне следовало уточнить, что имеется в виду работа на всех нормальных компиляторах.
                                                                          Сообщение отредактировано: Unreal Man -
                                                                            Цитата Unreal Man @
                                                                            Можно использовать постфиксный инкремент для элементарных типов и префиксный для пользовательских. Тем самым это разичие (с каким объектом идёт работа) будет наглядно подчёркиваться. Чем плох такой стиль?

                                                                            Зачем подчеркивать что идет работа с встроенным оператором инкремента??
                                                                            А если я его через 5 лет решу заменить на пользовательский тип? Что мне ходить везде инкременты править??
                                                                            Просто пишеться префиксный - и нет никогда, никакого гимороя, что бы не случилось. точка.

                                                                            Какието надуманные сигналы.. типа для одного типа пишем одно, для другого типа пишем другое.. гм. нафига?
                                                                            Есть понятие инкапсуляции, и лично я не хочу знаю с каким именно объектом я работаю. Я хочу знать только
                                                                            1) Что я с ним могу сделать.
                                                                            2) Как он должен откликаться на какие - либо стандартные действия(типа инкрементов).
                                                                            Все. Встроенный он, не встроенный - побарабану.
                                                                            Такой стиль - усложняет поддержку.
                                                                              Уважаемые господа спорщики, оцените, плз, насколько быстрее будет выполнятся такой код после замены всех постфиксов на префиксы. Сейчас я попробовал, очень интересный результат получился.
                                                                              ExpandedWrap disabled
                                                                                template <typename X> template <typename Y> std :: complex <X>
                                                                                   wave <X> :: operator () (const Y * y) const
                                                                                   {
                                                                                   complex ret (X (0.));
                                                                                   const Y * by = y, * ey = y + sz - 1;
                                                                                   for (complex * b = z;by < ey;b++, by++, ey--)
                                                                                      {
                                                                                      ret += complex (b->real () * (*by + *ey), b->imag () * (*ey - *by));
                                                                                      }
                                                                                   ret += X (*by) * mid ()->real ();
                                                                                   return ret;
                                                                                   }

                                                                              Это часть кода рабочей программы, которая была написана года 3 назад. Функция wave <X> :: operator () const вызавается в ходе выполнения программы порядка нескольких десятков миллионов раз, а потому время выполнения её очень критично.
                                                                              В данном случае X = float, Y = float;sz может изменяться в пределах от ~150 до 15000. изменение sz происходит не чаще чем 1 раз на 20000 вызовов, поэтому основные (99.9 %) вычислительные затраты приходятся на эту функцию.
                                                                              ЗЫ Среда разработки - BDS 2006, оптимизация максимальная по скорости.
                                                                                Цитата LuckLess @
                                                                                Зачем подчеркивать что идет работа с встроенным оператором инкремента??

                                                                                Затем, что в отношении невстроенных операторов нужна б́ольшая бдительность. Если для встроенных типов всё прозрачно, то пользовательский оператор может обладать некоторой спецификой (например, бросать исключение), не говоря уже о том, что в самом операторе может быть допущена банальная ошибка. Небольшая подсказка прямо в месте использования объекта не помешала бы.

                                                                                Цитата LuckLess @
                                                                                А если я его через 5 лет решу заменить на пользовательский тип? Что мне ходить везде инкременты править??

                                                                                Всё равно код наверняка придётся перепроверять. Заменить попутно формы инкрементов, думаю, особого труда не составит.

                                                                                Цитата LuckLess @
                                                                                Просто пишеться префиксный - и нет никогда, никакого гимороя, что бы не случилось.

                                                                                Пиши, я не против.

                                                                                Цитата LuckLess @
                                                                                Какието надуманные сигналы.. типа для одного типа пишем одно, для другого типа пишем другое.. гм. нафига?

                                                                                Ну, тебе-то, может, всё до лампады. Может, тебе и венгерская запись не нужна и комментарии тоже. Ну и что, всем теперь бегом твой стиль использовать?
                                                                                  Цитата Unreal Man @
                                                                                  Затем, что в отношении невстроенных операторов нужна б́ольшая бдительность. Если для встроенных типов всё прозрачно, то пользовательский оператор может обладать некоторой спецификой

                                                                                  Пользовательский опрератор не должен обладать никакой спецификой. Он должен быть идентичен обычным, встроенным операторам. Если нужна специфика - пиши встроенные функции - члены.

                                                                                  Цитата Unreal Man @
                                                                                  Всё равно код наверняка придётся перепроверять. Заменить попутно формы инкрементов, думаю, особого труда не составит

                                                                                  Да ну? Может прикажеш каждый мечяц все переписывать? Зато с инкрементами проблем не будет. У нас на работе используеться код 7-9 летней давности. И никто его переписывать не собираеться.

                                                                                  Цитата Unreal Man @
                                                                                  Ну, тебе-то, может, всё до лампады. Может, тебе и венгерская запись не нужна и комментарии тоже. Ну и что, всем теперь бегом твой стиль использовать?

                                                                                  Это не мой стиль. Может прочитал бы хоть какую книгу по С++ а?
                                                                                    Цитата antigen @
                                                                                    Уважаемые господа спорщики, оцените, плз, насколько быстрее будет выполнятся такой код после замены всех постфиксов на префиксы. Сейчас я попробовал, очень интересный результат получился.
                                                                                    ExpandedWrap disabled
                                                                                      template <typename X> template <typename Y> std :: complex <X>
                                                                                         wave <X> :: operator () (const Y * y) const
                                                                                         {
                                                                                         complex ret (X (0.));
                                                                                         const Y * by = y, * ey = y + sz - 1;
                                                                                         for (complex * b = z;by < ey;b++, by++, ey--)
                                                                                            {
                                                                                            ret += complex (b->real () * (*by + *ey), b->imag () * (*ey - *by));
                                                                                            }
                                                                                         ret += X (*by) * mid ()->real ();
                                                                                         return ret;
                                                                                         }

                                                                                    Это часть кода рабочей программы, которая была написана года 3 назад. Функция wave <X> :: operator () const вызавается в ходе выполнения программы порядка нескольких десятков миллионов раз, а потому время выполнения её очень критично.
                                                                                    В данном случае X = float, Y = float;sz может изменяться в пределах от ~150 до 15000. изменение sz происходит не чаще чем 1 раз на 20000 вызовов, поэтому основные (99.9 %) вычислительные затраты приходятся на эту функцию.
                                                                                    ЗЫ Среда разработки - BDS 2006, оптимизация максимальная по скорости.

                                                                                    Твой вывод?


                                                                                    Вообще, я как я понял, здесь очень многое упирается в компилятор, вернее в то, используется ли временная переменная в постфиксном инкременте или нет, согласитесь, если там стоит проверка на переполненние, компилятор не будет иметь никакого права избавиться от это временной переменной...
                                                                                      Цитата Russel @
                                                                                      согласитесь, если там стоит проверка на переполненние, компилятор не будет иметь никакого права избавиться от это временной переменной...

                                                                                      Об том и реч. Не всегда компилятор может оптимизировать наличие временной переменной.
                                                                                        Результаты экспериментов: (желающие могут повторить, возможно, у кого-то получатся иные)
                                                                                        постф. преф.
                                                                                        1 20 мин. 37 сек 20 мин. 37 сек.
                                                                                        2 4 мин. 05 сек 4 мин. 05 сек
                                                                                        Дальше мне стало в лом терять время на пустое экспериментирование.
                                                                                        Цитата Russel @
                                                                                        Твой вывод?

                                                                                        Вы хотите выводов ? Их есть у меня:
                                                                                        1. Градус обсуждения обратно пропорционален практической значимости темы.
                                                                                        2. Лучший помощник в вопросах производительности - дизассемблер и профайлер.
                                                                                        3. Похоже, эта тема тоже скоро перекочует в холивар.
                                                                                          Цитата antigen @
                                                                                          2. Лучший помощник в вопросах производительности - дизассемблер и профайлер.

                                                                                          Вот тут подерусь. Лучший помошник здравый смысл и профайлер :P :P
                                                                                            20 минут и 4 минуты???? ты не опечатался?

                                                                                            Добавлено
                                                                                            в смысле, что значит 1 и 2 у тебя?
                                                                                              Цитата Russel @
                                                                                              20 минут и 4 минуты???? ты не опечатался?

                                                                                              Это два разных эксперимента с разными наборами данных. (по строкам) Постфикс/префикс - по столбцам

                                                                                              Добавлено
                                                                                              Цитата LuckLess @
                                                                                              подерусь

                                                                                              Да пожалуйста, сколько угодно. Было-бы ещё за что.

                                                                                              Добавлено
                                                                                              Один из трёх вышеназванных самых верных помощников (угадайте какой) мне подсказывает, что очередной раз подтверждается один из трёх вышеприведённых выводов (угадайте какой). Впрочем, это уже не очень важно.
                                                                                                Цитата LuckLess @
                                                                                                Пользовательский опрератор не должен обладать никакой спецификой.

                                                                                                Это ещё почему?

                                                                                                Цитата LuckLess @
                                                                                                Он должен быть идентичен обычным, встроенным операторам.

                                                                                                Скорее, максимально похож. Но почему максимальная похожесть должна исключать специфичность?

                                                                                                Цитата LuckLess @
                                                                                                Если нужна специфика - пиши встроенные функции - члены.

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

                                                                                                Цитата LuckLess @
                                                                                                Да ну? Может прикажеш каждый мечяц все переписывать?

                                                                                                Утрировать всё, конечно, легко, но сомневаюсь, что в таких частых заменах может возникнуть реальная необходимость.

                                                                                                Цитата LuckLess @
                                                                                                Это не мой стиль. Может прочитал бы хоть какую книгу по С++ а?

                                                                                                А-а-а, теперь понял. Ты прочитал у Саттера рекомендацию использовать преф. форму и считаешь себя типа знатоком в этом вопросе :-)
                                                                                                  Цитата Unreal Man @
                                                                                                  Чтобы прибегать к использованию функций-членов, отказываясь от наглядных и простых в обращении операторов, нужна веская причина.

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

                                                                                                  Цитата Unreal Man @
                                                                                                  А-а-а, теперь понял. Ты прочитал у Саттера рекомендацию использовать преф. форму и считаешь себя типа знатоком в этом вопросе :-)

                                                                                                  :D :D Всетаки удивляет иногда способность некоторых индивидумов делать выводы. Можно поставить тебе пятерку за абстрактое мышление.
                                                                                                    Цитата LuckLess @
                                                                                                    Наглядность - это когда я вижу ++ и знаю что он делает

                                                                                                    Под «что он делает» можно понимать разные вещи: назначение и способ работы (читай внутреннее устройство). Я говорил про наглядность_использования_по_назначению.
                                                                                                      Цитата Unreal Man @
                                                                                                      наглядность_использования_по_назначению.

                                                                                                      назначение у ++ одно. Логически увеличивать экземпляр класса на логическую единицу тчк.
                                                                                                      Если ++ дает мне любого рода специфику, которая не дает мне возможности использовать его также как ++ для int - а, то на кой черт он нужен?? Где тут наглядность.. мне тогда надо лесть в исходники и смотреть чем именно отличаеться этот ++ от стандартного, да потом еще про это не забыть. И зачем мне эта специфичность нужна скажи? Лучше придумать название для некой функции - члена , отражающее ее специфичность и спокойно ее использовать.
                                                                                                      Иначе это вводит путаницу.
                                                                                                        Цитата Relan @
                                                                                                        Цитата Hryak @
                                                                                                        У некоторых POD-типов тоже могут быть перегруженные операторы. ;)
                                                                                                        Да, но речь-то о ++ и --. ;) Они ведь не могут быть перегружены (POD структуры не рассматриваем).

                                                                                                        Как это не рассматриваем? Сам же сказал про POD-типы. А POD-структуры и являются подмножеством POD-типов.

                                                                                                        -юсртыхэю
                                                                                                        Цитата Unreal Man @
                                                                                                        Цитата LuckLess @
                                                                                                        Наглядность - это когда я вижу ++ и знаю что он делает

                                                                                                        Под «что он делает» можно понимать разные вещи: назначение и способ работы (читай внутреннее устройство).

                                                                                                        Здесь понимается и то, и другое. Способ проистекает из назначения (с небольшими вариациями в реализации).
                                                                                                        Постфиксный ++, например, должен логически инкрементировать объект, при чем возвращать должен копию старого значения.
                                                                                                        Если кто-то закладывает в этот оператор что-то другое - этого программиста надо на мороз.
                                                                                                          Цитата LuckLess @
                                                                                                          назначение у ++ одно. Логически увеличивать экземпляр класса на логическую единицу тчк.
                                                                                                          Если ++ дает мне любого рода специфику, которая не дает мне возможности использовать его также как ++ для int - а, то на кой черт он нужен??

                                                                                                          Во-первых, с чего ты взял, что это логическое увеличение должно быть столь же тривиально, как у int? Кроме как в арифметике ++ больше нигде нельзя использовать?

                                                                                                          Во-вторых, даже по части арифметики не всё так гладко.

                                                                                                          Пусть имеется класс для работы с заоблачно большими числами. Память под число выделяется динамически (скажем, при помощи new). Когда число каким-то образом увеличивают, у него могут появиться новые разряды, под которые надо выделять доп. память. Выделение памяти – это уже своего рода специфика. Так что, теперь всё в функциях-членах считать?

                                                                                                          Пример так себе, но, думаю, суть ясна.
                                                                                                          Сообщение отредактировано: Unreal Man -
                                                                                                            Цитата Unreal Man @
                                                                                                            Во-первых, с чего ты взял, что это логическое увеличение должно быть столь же тривиально, как у int? Кроме как в арифметике ++ больше нигде нельзя использовать?

                                                                                                            Ты вообще читаешь или делаешь выводы по первым трем буквам?
                                                                                                            вчитываемся..
                                                                                                            Цитата

                                                                                                            Логически увеличивать экземпляр класса на логическую единицу тчк.

                                                                                                            А теперь отвечаем. причем тут арифметика?
                                                                                                              Цитата LuckLess @
                                                                                                              А теперь отвечаем. причем тут арифметика?

                                                                                                              А где ещё прокатит это твоё сравнение с int?
                                                                                                                Цитата Unreal Man @
                                                                                                                А где ещё прокатит это твоё сравнение с int?

                                                                                                                везде, где можно выделить операцию логического присваения и логическую единицу.
                                                                                                                  Цитата LuckLess @
                                                                                                                  Если ++ дает мне любого рода специфику, которая не дает мне возможности использовать его также как ++ для int - а, то на кой черт он нужен??

                                                                                                                  Если речь шла о возможности составления сложных выражений, то специфика не обязательно будет её исключать. Однако знать о специфике (или её возможном присутствии) всё равно желательно.
                                                                                                                  Сообщение отредактировано: Unreal Man -
                                                                                                                    Цитата Unreal Man @
                                                                                                                    Однако знать о специфике (или её возможном присутствии) всё равно желательно.

                                                                                                                    Т.е. с помощью ++i, а не i++ ты хочешь указать, что инкремент делается для объекта, отличного от встроенного типа, я тебя правильно понял?
                                                                                                                      Да :-) При беглом просмотре программы это будет своего рода подсказкой. Ведь когда видишь в гуще кода что-то вроде ++Name мысль в первую очередь возникает о каком-нибудь встроенном типе (ибо это самый распространённый вариант). Пока не увидишь определения, иногда и не поймёшь, что перед тобой возникло (если код уже давний и ты не помнишь деталей). Насчёт возможности во всех ситуациях строго разганичивать использование формы инкрементов по данному принципу я в общем-то не особо уверен (уже предвижу каверзные контрпримеры :-) ). Сам я таким разграничением не пользовался – просто выдвигаю его как вариант на всеобщую критику :-)
                                                                                                                        Цитата Unreal Man @
                                                                                                                        Да :-)

                                                                                                                        Т.е., специфику (объект невстроенного типа) в инкременте ты показать хочешь (кстати, а если результат инкремента должен использоваться в выражении, например: i++ + k - как ты собираешься указывать специфику? :lol:).
                                                                                                                        Как насчет других операций?
                                                                                                                        Например, m = i ? Здесь ведь тоже есть специфика - встроенный тип зачастую memcpy делает, пользовательский - фиг его знает. Сложно жить без возможности и тут указать специфику? :)
                                                                                                                        Предлагаю тебе юзать на выбор один из способов:
                                                                                                                        1. Отказаться от перегрузки операторов.
                                                                                                                        Знай себе пиши: i.VerySpecificIncrement(); m.VerySpecificAssigment(i) и т.д. "При беглом просмотре программы это будет " суперподсказкой о специфике, мимо которой не пройдешь.
                                                                                                                        2. Оставь перегрузку, но используй элемент венгерской нотации: помечай объекты всех невстроенных типов специальным префиксом. Тогда всегда будешь знать про специфику в выражениях: ++oi; om = oi; и т.п. По сути, то, что ты предлагаешь - аналог такой нотации, просто выраженный не в названиях переменных, а в использовании/неиспользовании отдельных языковых конструкций. Но думаю, поклонников твоей нотации гораздо меньше, чем поклонников венгерской. :)
                                                                                                                        Сообщение отредактировано: Hryak -
                                                                                                                          Цитата Hryak @
                                                                                                                          Т.е., специфику (объект невстроенного типа) в инкременте ты показать хочешь

                                                                                                                          Всего лишь её возможное наличие, если точнее.

                                                                                                                          Цитата Hryak @
                                                                                                                          кстати, а если результат инкремента должен использоваться в выражении, например: i++ + k - как ты собираешься указывать специфику?

                                                                                                                          Цитата Hryak @
                                                                                                                          Как насчет других операций?

                                                                                                                          Эк куда тебя погнало-то :-) Ну, ясное дело, что никак.

                                                                                                                          Цитата Hryak @
                                                                                                                          Предлагаю тебе юзать на выбор один из способов:

                                                                                                                          Ты не поверишь, но о них я уже думал :-)

                                                                                                                          Цитата Hryak @
                                                                                                                          Знай себе пиши: i.VerySpecificIncrement(); m.VerySpecificAssigment(i) и т.д.

                                                                                                                          Громоздко, однако. Очень громоздко.

                                                                                                                          Цитата Hryak @
                                                                                                                          Оставь перегрузку, но используй элемент венгерской нотации

                                                                                                                          Тоже удлинение имени :-) Венгерскую нотацию использую в основном лишь для булевых переменных и указателей. Может, с помощью регистра начальной буквы их различать?
                                                                                                                            Цитата Unreal Man @
                                                                                                                            Эк куда тебя погнало-то :-) Ну, ясное дело, что никак.

                                                                                                                            Ясно, что никак. Но ведь тебе хотелось бы?

                                                                                                                            Цитата
                                                                                                                            Громоздко, однако. Очень громоздко.

                                                                                                                            Названия я для примера привел. Можно и покороче обозвать - все равно вызов фукнции не будет смахивать на использование оператора - обозначение возможной специфики не пропадет. :) Кстати, можно заюзать и i.operator++(), i.operator++(0), m.operator=(i) :D

                                                                                                                            Цитата
                                                                                                                            Тоже удлинение имени :-)

                                                                                                                            На одну букву? Это не довод. Одна буква, а показывает возможную специфику в любом контексте использования объекта. То, что ты предложил - это половинчатое(даже не половинчатое, а 1/xx) решение, т.к. охватывает только два оператора из десятков возможных, и то, не всегда применимое.

                                                                                                                            Цитата
                                                                                                                            Может, с помощью регистра начальной буквы их различать?

                                                                                                                            Ну, если в твоем naming convention заглавная буква ничего еще не означает (ни верблюдов, ни прочих животных не наблюдается) - различай так.
                                                                                                                            Сообщение отредактировано: Hryak -
                                                                                                                              Цитата antigen @
                                                                                                                              Результаты экспериментов: (желающие могут повторить, возможно, у кого-то получатся иные)
                                                                                                                              А другой результат тут трудно ожидать. Инкремент/декремент адреса легко оптимизируем и весьма быстр, не думаю, что в этом кто-то сомневается. Ты попробуй какой-нибудь тип, например, длинной арифметики поинкрементировать/декрементировать.
                                                                                                                              А отсюда и такие выводы.

                                                                                                                              Добавлено
                                                                                                                              Хотя бы такую функцию:
                                                                                                                              ExpandedWrap disabled
                                                                                                                                template <class T>
                                                                                                                                int dummy_function(const T& max_counter) {
                                                                                                                                   int result = 0;
                                                                                                                                #ifdef TEST_PREINCREMENT
                                                                                                                                   for( T i=0 ; i < max_counter ; ++i ) {
                                                                                                                                #else
                                                                                                                                   for( T i=0 ; i < max_counter ; i++ ) {
                                                                                                                                #endif
                                                                                                                                      if( i%2 )
                                                                                                                                         ++result;
                                                                                                                                   }
                                                                                                                                   return result;
                                                                                                                                }
                                                                                                                              Кстати, как тут инкрементом обозначать "специфику типа"?
                                                                                                                                Цитата Hryak @
                                                                                                                                Можно и покороче обозвать

                                                                                                                                Цитата Hryak @
                                                                                                                                Кстати, можно заюзать и i.operator++(), i.operator++(0), m.operator=(i)

                                                                                                                                Можно-то оно можно, но, сам понимаешь, такая запись выглядит уже не столь коротко и красиво.

                                                                                                                                Цитата Hryak @
                                                                                                                                На одну букву? Это не довод.

                                                                                                                                Вот и я так считал, пока не попробовал такое использовать :-) Если есть вложенность классов, то при обращении типа oName1.oName2.oName3.oName4 выглядит это как-то очень.

                                                                                                                                Цитата Hryak @
                                                                                                                                То, что ты предложил - это половинчатое(даже не половинчатое, а 1/xx) решение, т.к. охватывает только два оператора из десятков возможных

                                                                                                                                Заметь, по сравнению с некоторыми остальными операторами, ++ и –– в user defined виде используются несколько пореже.

                                                                                                                                Цитата Hryak @
                                                                                                                                Ну, если в твоем naming convention заглавная буква ничего еще не означает

                                                                                                                                Похожее написание будет у функций. Однако неясность это станет вносить лишь при взятии адреса.

                                                                                                                                Цитата trainer @
                                                                                                                                Кстати, как тут инкрементом обозначать "специфику типа"?

                                                                                                                                Неизвестный тип T – это уже возможная специфика. Хотя в случае со счётчиком это вряд ли...
                                                                                                                                  Цитата Unreal Man @
                                                                                                                                  Неизвестный тип T – это уже возможная специфика.
                                                                                                                                  Ты не темни, прямо скажи, какой вариант использовать? ;) Преинкремент или постинкремент?
                                                                                                                                  А чтобы шаблон не смущал можно написать так:
                                                                                                                                  ExpandedWrap disabled
                                                                                                                                    #if 0
                                                                                                                                    typedef int counter_type;
                                                                                                                                    #else
                                                                                                                                    typedef что-то большое counter_type;
                                                                                                                                    #endif
                                                                                                                                     
                                                                                                                                    int dummy_function(const counter_type& max_counter) {
                                                                                                                                       int result = 0;
                                                                                                                                    #ifdef TEST_PREINCREMENT
                                                                                                                                       for( counter_type i=0 ; i < max_counter ; ++i ) {
                                                                                                                                    #else
                                                                                                                                       for( counter_type i=0 ; i < max_counter ; i++ ) {
                                                                                                                                    #endif
                                                                                                                                          if( i%2 )
                                                                                                                                             ++result;
                                                                                                                                       }
                                                                                                                                       return result;
                                                                                                                                    }
                                                                                                                                  Или так:
                                                                                                                                  ExpandedWrap disabled
                                                                                                                                    #define count_something(counter_type, max_value, result) \
                                                                                                                                       do { \
                                                                                                                                          counter_type i = 0; \
                                                                                                                                          result = 0; \
                                                                                                                                          for( ; i < max_value ; ++i ) \
                                                                                                                                             if( i%2 ) \
                                                                                                                                                ++result; \
                                                                                                                                       } while( 0 )
                                                                                                                                  ++i или i++ надлежит писать? Как обозначить специфику?
                                                                                                                                  Сообщение отредактировано: trainer -
                                                                                                                                    Цитата Unreal Man @
                                                                                                                                    Да :-) При беглом просмотре программы это будет своего рода подсказкой. Ведь когда видишь в гуще кода что-то вроде ++Name мысль в первую очередь возникает о каком-нибудь встроенном типе (ибо это самый распространённый вариант). Пока не увидишь определения, иногда и не поймёшь, что перед тобой возникло (если код уже давний и ты не помнишь деталей).

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

                                                                                                                                    Ну и вообще использовать инкремент в качестве подскаки о типе... :blink: :blink:
                                                                                                                                    Могу подкинуть идею: если у тебя большой участок кода будет без инкрементов, то ты делай такие вставочки
                                                                                                                                    ExpandedWrap disabled
                                                                                                                                      val++;
                                                                                                                                      val--; // а это чтобы значение не изменилось

                                                                                                                                    А то вдруг забудешь какой там тип встроенный или нет :lol:
                                                                                                                                      Цитата trainer @
                                                                                                                                      Ты не темни, прямо скажи, какой вариант использовать?

                                                                                                                                      Если считаешь возможным определение counter_type в виде пользовательского типа, то префиксный. Если же нет – постфиксный (тем самым ты только подчеркнёшь, что под этим загадочным counter_type скрывается именно какой-то элементарный тип).

                                                                                                                                      Цитата trainer @
                                                                                                                                      ++i или i++ надлежит писать? Как обозначить специфику?

                                                                                                                                      Ещё раз: речь идёт об обозначении возможного наличия специфики.

                                                                                                                                      Цитата Alex437 @
                                                                                                                                      Если просматривая код ты не понимаешь, что перед тобой "возникает", то тут никакие подсказки не помогут.

                                                                                                                                      Речь идёт о том, сколько кода тебе нужно просмотреть, и сколько времени у тебя уйдёт на то, чтобы это понять.

                                                                                                                                      Цитата Alex437 @
                                                                                                                                      Ну и вообще использовать инкремент в качестве подскаки о типе...

                                                                                                                                      А что, когда ты видишь в коде ++, у тебя никаких мыслей по поводу типа объекта не возникает? Инкремент сам по себе уже является определённой подсказкой о типе. Здесь лишь добавляется дополнительная информация.

                                                                                                                                      Цитата Alex437 @
                                                                                                                                      Могу подкинуть идею: если у тебя большой участок кода будет без инкрементов, то ты делай такие вставочки

                                                                                                                                      Типо смешно. Речь-то идёт скорее о том, что при виде ++ легко ввести себя в заблуждение, приняв объект за переменную встроенного типа (поскольку в большинстве случаев, когда видишь подобный кусок кода, это действительно так). Использование свободной префиксной формы может выступать в роли подсказки о том, что это впечатление вероятно может оказаться ошибочным.
                                                                                                                                      Сообщение отредактировано: Unreal Man -
                                                                                                                                        Unreal Man
                                                                                                                                        Угу. Есть уже способ чтобы обозначить тип.
                                                                                                                                        2 таких способа не нужно. Чем больше, тем хуже в данном случае.

                                                                                                                                        Если когда ты видиш ++ у тебя возникает задняя мысль поп оводу типа объекта..то хух.. это по крайней мере странно. О типе должен говорить ИДЕНТИФИКАТОР и только он.
                                                                                                                                        Такого рода использование ++ и -- идет в ущерб расширяемости и гибкости, к томуже вносит лишнюю и ненужную информацию, которую должен помнить программист.
                                                                                                                                          Цитата Unreal Man @
                                                                                                                                          Если считаешь возможным определение counter_type в виде пользовательского типа, то префиксный.
                                                                                                                                          Я считаю возможным определение любого типа как пользовательского. Причем сейчас я не знаю, что потребуется через месяц. А ты - не считаешь?
                                                                                                                                          Цитата Unreal Man @
                                                                                                                                          Ещё раз: речь идёт об обозначении возможного наличия специфики.
                                                                                                                                          Для меня это звучит примерно как "наполовину беременна". Наличие специфики всегда возможно.
                                                                                                                                          Цитата Unreal Man @
                                                                                                                                          А что, когда ты видишь в коде ++, у тебя никаких мыслей по поводу типа объекта не возникает?
                                                                                                                                          А какие мысли должны возникать? Ну если только "откомпилируется или нет?" Мне все время казалось, что типы созданы для того, чтобы не задумываться о том, как они устроены.
                                                                                                                                            Цитата Unreal Man @
                                                                                                                                            А что, когда ты видишь в коде ++, у тебя никаких мыслей по поводу типа объекта не возникает?

                                                                                                                                            Нет, не возникает. Обычно тип объекта я определяю несколько иными способами. И мне всегда надо знать точный тип объекта, а не просто видеть встроенный он или нет.
                                                                                                                                            А у тебя получается, что ты не знаешь тип объекта и следовательно не знаешь его роль в программе. Но видишь, что он инкрементируется и начинаешь предполагать, что вероятно он пользовательского типа... Так?
                                                                                                                                            А что это за объект и зачем он инкрементируется - это наверно долго и скучно разбираться? :lol:
                                                                                                                                            Извини, но мне это и вправду забавным кажется... Я собственно даже не пойму, ты всерьез это пишешь или издеваешься?
                                                                                                                                            Сообщение отредактировано: Alex437 -
                                                                                                                                              Страуструп, издание за 98г, стр 629.
                                                                                                                                              Отметим, что пост-инкремент используе промежуточную переменную, а пре-инкремент нет.
                                                                                                                                              По это причине, для итераторов предпочтительнее ++p, а не p++.
                                                                                                                                                Цитата trainer @
                                                                                                                                                Цитата (Unreal Man @ 8.06.06, 11:52)
                                                                                                                                                Если считаешь возможным определение counter_type в виде пользовательского типа, то префиксный.
                                                                                                                                                Я считаю возможным определение любого типа как пользовательского. Причем сейчас я не знаю, что потребуется через месяц. А ты - не считаешь?
                                                                                                                                                :yes: К тому ж это вообще может быть библиотечный код - и использовать его будет незнамо - кто, незнамо - когда, незнамо - с каким типом.
                                                                                                                                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                                                                                                0 пользователей:


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