
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.86] |
![]() |
|
Сообщ.
#1
,
|
|
|
Привет всем!
Бытует мнение, что использования префиксного инкремента или декремента (по-русски ++i --i) дает незначительную оптимизацию, по сравнению с постфиксным (по-русски i++ i--) Ваше мнение? Используете в своих проектах? P.S. я имею ввиду проекты, где очень важна скорость... |
Сообщ.
#2
,
|
|
|
использую постфиксный ТОЛЬКО когда это необходимо.
Цитата Russel @ Бытует мнение, что использования префиксного инкремента или декремента (по-русски ++i --i) дает незначительную оптимизацию иногда, очень даже значительную оптимизацию. |
Сообщ.
#3
,
|
|
|
Если производится инкремент/декремент POD-типа, то пофигу. Если это перегруженный оператор, то всё зависит от его реализации. Обычно постфиксный ин(де)кремент реализуется через префиксный. А вообще, это несущественная мелочь, не в тех местах неэффективность ищешь.
![]() |
Сообщ.
#4
,
|
|
|
Цитата Relan @ Если производится инкремент/декремент POD-типа, то пофигу. Если это перегруженный оператор, то всё зависит от его реализации. У некоторых POD-типов тоже могут быть перегруженные операторы. ![]() |
![]() |
Сообщ.
#5
,
|
|
Для перегруженных операторов ВСЕГДА быстрее префиксный
|
Сообщ.
#6
,
|
|
|
Цитата arcsupport @ Для перегруженных операторов ВСЕГДА быстрее префиксный ![]() ![]() в общем случае неверно. Но если говорить о перегруженных и стандартно себя ведущих операторах, то да, в огромном большинстве случаев постфиксный будет вести себя медленней. |
Сообщ.
#7
,
|
|
|
Цитата LuckLess @ Но если говорить о перегруженных и стандартно себя ведущих операторах, то да, в огромном большинстве случаев постфиксный будет вести себя медленней Согласен. Ведь по логике вещей префиксный сразу прибавляет единицу и ненужну никакого левого кода. А ситуацию с постфиксным надо определять... |
Сообщ.
#8
,
|
|
|
Цитата Relan @ А вообще, это несущественная мелочь, не в тех местах неэффективность ищешь. ![]() Копейка рубль бережет... |
Сообщ.
#9
,
|
|
|
Я компилирую все Интеловским компилятором, у меня разницы нет... скорее всего, он фиксит такие вещи и оптимизирует их по умолчанию...
Это наверно больше вопрос стиля, или предубеждений... Есть у кого-нибудь еще мнения? Добавлено Да забыл сказать - чистый С (без классов) |
Сообщ.
#10
,
|
|
|
Использую только префиксный вариант. Соглашусь с тем, что:
Цитата А вообще, это несущественная мелочь, не в тех местах неэффективность ищешь. |
Сообщ.
#11
,
|
|
|
Цитата Russel @ Правильно реализованные перегруженные префиксные инкремент/декремент как правило не медленнее(если не быстрее) постфиксных. Т.к. последние требуют создания копии объекта, хранящей предыдущее значение. Это наверно больше вопрос стиля, или предубеждений... |
Сообщ.
#12
,
|
|
|
Цитата Russel @ Да забыл сказать - чистый С (без классов) ничего себе приписочка ![]() ![]() Конечно,в Чистом С - пофигу, т.к. перегрузки операторов в нем нет ![]() |
Сообщ.
#13
,
|
|
|
Цитата Relan @ Если производится инкремент/декремент POD-типа, то пофигу. Разве для POD-типа постфиксный инкремент не должен создавать и возвращать временную переменную со старым значением? ![]() |
Сообщ.
#14
,
|
|
|
Цитата Alex437 @ Разве для POD-типа постфиксный инкремент не должен создавать и возвращать временную переменную со старым значением? ![]() int wah; wah++; ... ну вернет int... и че?)) в любом случае меньше инта не вернеться... |
Сообщ.
#15
,
|
|
|
Лично я использую постфиксный. С проектами где скорость крайне критична не работал, а вот глазу - проще
![]() |
Сообщ.
#16
,
|
|
|
Цитата Мяут @ а вот глазу - проще ![]() ну этт на любителя.. лично мне уже i++ в глазак ребит..)) сразу вижу.. и правлю, правлю ![]() |
Сообщ.
#17
,
|
|
|
Цитата LuckLess @ int wah; wah++; ... ну вернет int... и че?)) Да просто зачем создавать лишнюю переменную, которая никому не нужна? Получаются совершенно лишние действия. Тем более что их так просто избежать - всего лишь нарисовать плюсики спереди ![]() Цитата лично мне уже i++ в глазак ребит..)) сразу вижу.. и правлю, правлю ![]() |
Сообщ.
#18
,
|
|
|
Цитата Alex437 @ Получаются совершенно лишние действия. Нету там никаких лишних действий (на нормальных компиляторах). Свободный i++ делает то же самое, что ++i. Цитата Alex437 @ аналогично ![]() ![]() m++; m*=n; ![]() ![]() ++m; m*=n; Где лучше просматривается модификация m? В первом примере m везде находится слева, что легко замечается при беглом просмотре кода. |
![]() |
Сообщ.
#19
,
|
|
Ребята, о вкусах не спорят.
А что касается совместимости и удобства - лучше использовать префиксный |
Сообщ.
#20
,
|
|
|
Цитата Unreal Man @ Свободный i++ делает то же самое, что ++i. Это потому что компилятор оптимизирует. А в языке C++ нет понятия "свободного инкремента" и "несвободного инкремента". И ничего не может зависеть от того, что он там свободный. |
Сообщ.
#21
,
|
|
|
Цитата Нету там никаких лишних действий. Свободный i++ делает то же самое, что ++i. результат здесь один и тотже, а действия разные в том числе и лишние. Надо четко разделять почему x = y[++i] и x = y[i++] дадут разные результаты. А отношение типа "а пофиг - это одно и тоже" это не аргумент, а источник ошибок Добавлено да, забыл - я за префикс... |
Сообщ.
#22
,
|
|
|
Unreal Man, ты лучше объясни какая разница между "свободным i++" и "несвободным i++"
|
Сообщ.
#23
,
|
|
|
А разве не понятно? У свободного i++ значение оператора никем не используется.
|
Сообщ.
#24
,
|
|
|
Я имею в виду с точки зрения производительности.
|
Сообщ.
#25
,
|
|
|
Цитата Unreal Man @ Даже у меня на JavaScript не видно никакой разницы между свободными i++ и ++i :-) Хочешь писать программы под какой-то абстрактный компилятор C++ в надежде, что где-то ++i увеличит производительность – пиши на здоровье :-) Постфиксный ++ практически всегда медленне для не ПОД типов. Перед тем как это писать подумал бы.. компилятор не в праве оптимизировать постфиксный ++ префиксным, вне зависимости от того свободный он или нет для не POD типов. И он не только не в праве, а он и не делает этого. Добавлено И причем тут втой ДжаваСкрипт вообще? |
Сообщ.
#26
,
|
|
|
Цитата Unreal Man @ Хочешь писать программы под какой-то абстрактный компилятор C++ в надежде, что где-то ++i увеличит производительность – пиши на здоровье :-) Я не под абстрактный компилятор пишу, я просто не люблю перекладывать на компилятор оптимизацию, которую вполне могу сделать сам. |
Сообщ.
#27
,
|
|
|
Цитата Unreal Man @ Лучше писать ++i зная, что какой-то компилятор C++ не уменьшит производительность Хочешь писать программы под какой-то абстрактный компилятор C++ в надежде, что где-то ++i увеличит производительность – пиши на здоровье ![]() ![]() |
Сообщ.
#28
,
|
|
|
Цитата Hryak @ Да, но речь-то о ++ и --. У некоторых POD-типов тоже могут быть перегруженные операторы. ![]() ![]() Цитата Russel @ Я использую постфиксные для POD и префиксные для классов, включая итераторы (которые на самом деле могут быть указательями). Мне так проще. Это наверно больше вопрос стиля, или предубеждений... Цитата Alex437 @ Должен. Но если это значение имеет смысл, то тогда и спорить не о чем, т.к. использование того или иного опреатора определяется семантикой. Разве для POD-типа постфиксный инкремент не должен создавать и возвращать временную переменную со старым значением? ![]() Цитата Alex437 @ Господа, не надо считать оптимизатор дурачком. Да просто зачем создавать лишнюю переменную, которая никому не нужна? ![]() |
Сообщ.
#29
,
|
|
|
Цитата Relan @ Да, но речь-то о ++ и --. ![]() Почемуйто ПОД структуры не рассматриваем??)) Вообще, если обобщить, то постфиксный практически 100% медленней префиксного для любого ползовательского оператора, по барабану ПОД тип или нет.. |
Сообщ.
#30
,
|
|
|
Цитата Relan @ Господа, не надо считать оптимизатор дурачком. ![]() Про оптимизацию компилятором я уже писал в предыдущем посте. Я его дурачком не считаю, но и я тоже не дурачок ![]() |
Сообщ.
#31
,
|
|
|
На оптимизатор надейся, а сам не плошай.
Префиксный инкремент где только возможно, постфиксный инкремент только при необходимости. |
Сообщ.
#32
,
|
|
|
Цитата Relan @ Я использую постфиксные для POD и префиксные для классов ![]() ![]() typedef что-то my_type; for( my_type i=0 ; i < 10 ; какой будешь использовать? ); |
Сообщ.
#33
,
|
|
|
Цитата Alex437 @ Я имею в виду с точки зрения производительности. Не пойму, к чему ты клонишь. Можно предположить, что свободному i++ незачем создавать копию (т.е. лишних действий делать не нужно). Цитата trainer @ Лучше писать ++i зная, что какой-то компилятор C++ не уменьшит производительность Если всё идеализировать, то да. С практической же точки зрения это преимущество мизерно. P.S. Оффтоп (извиняюсь, но давно хотел сказать пару ласковых LuckLess и чтоб в присутствии других :-) ) Цитата LuckLess @ Постфиксный ++ практически всегда медленне для не ПОД типов. Перед тем как это писать подумал бы.. А к чему я, по-твоему, пишу i? Это обычное имя для целочисленного счётчика. При чём тут не-POD типы? Ты вообще о чём? :-) Открой свои глазки и проследи за ходом дискуссии. Цитата LuckLess @ И он не только не в праве, а он и не делает этого. О, сбасибо, что просветил! :-) Где ты увидел хотя бы намёк на то, что речь идёт о пользовательских типах? Ёжику понятно, что в отношении польз. типов нужно смотреть на конкретную реализацию инкрементов. Цитата LuckLess @ И причем тут втой ДжаваСкрипт вообще? При том, что тут нету никакого компилятора, а разницы всё равно не видно никакой. На размышления не наводит? Далее. Твои игры с рейтингами – это вообще детсад :-) Наверно, никто на форуме не печётся о них больше, чем ты. И это при том, что ты сам бегом и вприпрыжку несёшься отвечать во все темы, порой уверенно выдавая за факты свои непродуманные домыслы (которые не всегда оказываются верными). Если бы я ставил тебе по минусу за каждый твой неудачный перл, у тебя бы уже с десяток твоих любимых очков поубавилось. Хочешь, я этим займусь? :-) |
Сообщ.
#34
,
|
|
|
Unreal Man
Уфф.. ты навернякак пришел в С++ из асма.. да можно писать для int-а и постфиксный инкремент, причем не обязательно для "свободных" интов, а можно и для любых. вот к примеру ![]() ![]() 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) Джава скрипт вообще никакого отношения к делу не имеет. по поводу остального - думай обо мне что угодно, мне от этого ни теплей, ни холодней. |
Сообщ.
#35
,
|
|
|
Цитата Unreal Man @ Не пойму, к чему ты клонишь. Можно предположить, что свободному i++ незачем создавать копию (т.е. лишних действий делать не нужно). Я тебе еще раз говорю, что нет никакого "свободного постфиксного инкремента" и "несвободного постфиксного инкремента" (если не веришь - загляни в стандарт ![]() Есть просто постфиксный инкремент и работает он везде одинаково, он просто по определению должен возвращать временную переменную (пока компилятор не сомптимизирует). |
Сообщ.
#36
,
|
|
|
Цитата LuckLess @ ты навернякак пришел в С++ из асма.. Не угадал – из Delphi (но это снова оффтоп) Цитата LuckLess @ отчличий никаких(в плане производительности. Может, мой тест был кривой, но с посфиксным++ аналогичная работа шла процентов на 20 быстрее :-) Цитата LuckLess @ 2) Всегда лучше придерживаться одного стиля. Можно использовать постфиксный инкремент для элементарных типов и префиксный для пользовательских. Тем самым это различие (с каким объектом идёт работа) будет наглядно подчёркиваться. Чем плох такой стиль? Цитата LuckLess @ 3) Джава скрипт вообще никакого отношения к делу не имеет. Ну если тебя это успокоит, то пускай будет так :-) Цитата Alex437 @ Я тебе еще раз говорю, что нет никакого "свободного постфиксного инкремента" Не надо мне это объяснять – я всё прекрасно понимаю :-) Пожалуй, мне следовало уточнить, что имеется в виду работа на всех нормальных компиляторах. |
Сообщ.
#37
,
|
|
|
Цитата Unreal Man @ Можно использовать постфиксный инкремент для элементарных типов и префиксный для пользовательских. Тем самым это разичие (с каким объектом идёт работа) будет наглядно подчёркиваться. Чем плох такой стиль? Зачем подчеркивать что идет работа с встроенным оператором инкремента?? А если я его через 5 лет решу заменить на пользовательский тип? Что мне ходить везде инкременты править?? Просто пишеться префиксный - и нет никогда, никакого гимороя, что бы не случилось. точка. Какието надуманные сигналы.. типа для одного типа пишем одно, для другого типа пишем другое.. гм. нафига? Есть понятие инкапсуляции, и лично я не хочу знаю с каким именно объектом я работаю. Я хочу знать только 1) Что я с ним могу сделать. 2) Как он должен откликаться на какие - либо стандартные действия(типа инкрементов). Все. Встроенный он, не встроенный - побарабану. Такой стиль - усложняет поддержку. |
Сообщ.
#38
,
|
|
|
Уважаемые господа спорщики, оцените, плз, насколько быстрее будет выполнятся такой код после замены всех постфиксов на префиксы. Сейчас я попробовал, очень интересный результат получился.
![]() ![]() 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, оптимизация максимальная по скорости. |
Сообщ.
#39
,
|
|
|
Цитата LuckLess @ Зачем подчеркивать что идет работа с встроенным оператором инкремента?? Затем, что в отношении невстроенных операторов нужна б́ольшая бдительность. Если для встроенных типов всё прозрачно, то пользовательский оператор может обладать некоторой спецификой (например, бросать исключение), не говоря уже о том, что в самом операторе может быть допущена банальная ошибка. Небольшая подсказка прямо в месте использования объекта не помешала бы. Цитата LuckLess @ А если я его через 5 лет решу заменить на пользовательский тип? Что мне ходить везде инкременты править?? Всё равно код наверняка придётся перепроверять. Заменить попутно формы инкрементов, думаю, особого труда не составит. Цитата LuckLess @ Просто пишеться префиксный - и нет никогда, никакого гимороя, что бы не случилось. Пиши, я не против. Цитата LuckLess @ Какието надуманные сигналы.. типа для одного типа пишем одно, для другого типа пишем другое.. гм. нафига? Ну, тебе-то, может, всё до лампады. Может, тебе и венгерская запись не нужна и комментарии тоже. Ну и что, всем теперь бегом твой стиль использовать? |
Сообщ.
#40
,
|
|
|
Цитата Unreal Man @ Затем, что в отношении невстроенных операторов нужна б́ольшая бдительность. Если для встроенных типов всё прозрачно, то пользовательский оператор может обладать некоторой спецификой Пользовательский опрератор не должен обладать никакой спецификой. Он должен быть идентичен обычным, встроенным операторам. Если нужна специфика - пиши встроенные функции - члены. Цитата Unreal Man @ Всё равно код наверняка придётся перепроверять. Заменить попутно формы инкрементов, думаю, особого труда не составит Да ну? Может прикажеш каждый мечяц все переписывать? Зато с инкрементами проблем не будет. У нас на работе используеться код 7-9 летней давности. И никто его переписывать не собираеться. Цитата Unreal Man @ Ну, тебе-то, может, всё до лампады. Может, тебе и венгерская запись не нужна и комментарии тоже. Ну и что, всем теперь бегом твой стиль использовать? Это не мой стиль. Может прочитал бы хоть какую книгу по С++ а? |
Сообщ.
#41
,
|
|
|
Цитата antigen @ Уважаемые господа спорщики, оцените, плз, насколько быстрее будет выполнятся такой код после замены всех постфиксов на префиксы. Сейчас я попробовал, очень интересный результат получился. ![]() ![]() 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, оптимизация максимальная по скорости. Твой вывод? Вообще, я как я понял, здесь очень многое упирается в компилятор, вернее в то, используется ли временная переменная в постфиксном инкременте или нет, согласитесь, если там стоит проверка на переполненние, компилятор не будет иметь никакого права избавиться от это временной переменной... |
Сообщ.
#42
,
|
|
|
Цитата Russel @ согласитесь, если там стоит проверка на переполненние, компилятор не будет иметь никакого права избавиться от это временной переменной... Об том и реч. Не всегда компилятор может оптимизировать наличие временной переменной. |
Сообщ.
#43
,
|
|
|
Результаты экспериментов: (желающие могут повторить, возможно, у кого-то получатся иные)
постф. преф. 1 20 мин. 37 сек 20 мин. 37 сек. 2 4 мин. 05 сек 4 мин. 05 сек Дальше мне стало в лом терять время на пустое экспериментирование. Цитата Russel @ Твой вывод? Вы хотите выводов ? Их есть у меня: 1. Градус обсуждения обратно пропорционален практической значимости темы. 2. Лучший помощник в вопросах производительности - дизассемблер и профайлер. 3. Похоже, эта тема тоже скоро перекочует в холивар. |
Сообщ.
#44
,
|
|
|
Цитата antigen @ 2. Лучший помощник в вопросах производительности - дизассемблер и профайлер. Вот тут подерусь. Лучший помошник здравый смысл и профайлер ![]() ![]() |
Сообщ.
#45
,
|
|
|
20 минут и 4 минуты???? ты не опечатался?
Добавлено в смысле, что значит 1 и 2 у тебя? |
Сообщ.
#46
,
|
|
|
Цитата Russel @ 20 минут и 4 минуты???? ты не опечатался? Это два разных эксперимента с разными наборами данных. (по строкам) Постфикс/префикс - по столбцам Добавлено Цитата LuckLess @ подерусь Да пожалуйста, сколько угодно. Было-бы ещё за что. Добавлено Один из трёх вышеназванных самых верных помощников (угадайте какой) мне подсказывает, что очередной раз подтверждается один из трёх вышеприведённых выводов (угадайте какой). Впрочем, это уже не очень важно. |
Сообщ.
#47
,
|
|
|
Цитата LuckLess @ Пользовательский опрератор не должен обладать никакой спецификой. Это ещё почему? Цитата LuckLess @ Он должен быть идентичен обычным, встроенным операторам. Скорее, максимально похож. Но почему максимальная похожесть должна исключать специфичность? Цитата LuckLess @ Если нужна специфика - пиши встроенные функции - члены. Чтобы прибегать к использованию функций-членов, отказываясь от наглядных и простых в обращении операторов, нужна веская причина. Цитата LuckLess @ Да ну? Может прикажеш каждый мечяц все переписывать? Утрировать всё, конечно, легко, но сомневаюсь, что в таких частых заменах может возникнуть реальная необходимость. Цитата LuckLess @ Это не мой стиль. Может прочитал бы хоть какую книгу по С++ а? А-а-а, теперь понял. Ты прочитал у Саттера рекомендацию использовать преф. форму и считаешь себя типа знатоком в этом вопросе :-) |
Сообщ.
#48
,
|
|
|
Цитата Unreal Man @ Чтобы прибегать к использованию функций-членов, отказываясь от наглядных и простых в обращении операторов, нужна веская причина. Гы. Наглядность - это когда я вижу ++ и знаю что он делает, а это исключает любого рода специфику ++ - са. Если есть специфика - наглядность обманчива и вредна. Цитата Unreal Man @ А-а-а, теперь понял. Ты прочитал у Саттера рекомендацию использовать преф. форму и считаешь себя типа знатоком в этом вопросе :-) ![]() ![]() |
Сообщ.
#49
,
|
|
|
Цитата LuckLess @ Наглядность - это когда я вижу ++ и знаю что он делает Под «что он делает» можно понимать разные вещи: назначение и способ работы (читай внутреннее устройство). Я говорил про наглядность_использования_по_назначению. |
Сообщ.
#50
,
|
|
|
Цитата Unreal Man @ наглядность_использования_по_назначению. назначение у ++ одно. Логически увеличивать экземпляр класса на логическую единицу тчк. Если ++ дает мне любого рода специфику, которая не дает мне возможности использовать его также как ++ для int - а, то на кой черт он нужен?? Где тут наглядность.. мне тогда надо лесть в исходники и смотреть чем именно отличаеться этот ++ от стандартного, да потом еще про это не забыть. И зачем мне эта специфичность нужна скажи? Лучше придумать название для некой функции - члена , отражающее ее специфичность и спокойно ее использовать. Иначе это вводит путаницу. |
Сообщ.
#51
,
|
|
|
Цитата Relan @ Цитата Hryak @ Да, но речь-то о ++ и --. У некоторых POD-типов тоже могут быть перегруженные операторы. ![]() ![]() Как это не рассматриваем? Сам же сказал про POD-типы. А POD-структуры и являются подмножеством POD-типов. -юсртыхэю Цитата Unreal Man @ Цитата LuckLess @ Наглядность - это когда я вижу ++ и знаю что он делает Под «что он делает» можно понимать разные вещи: назначение и способ работы (читай внутреннее устройство). Здесь понимается и то, и другое. Способ проистекает из назначения (с небольшими вариациями в реализации). Постфиксный ++, например, должен логически инкрементировать объект, при чем возвращать должен копию старого значения. Если кто-то закладывает в этот оператор что-то другое - этого программиста надо на мороз. |
Сообщ.
#52
,
|
|
|
Цитата LuckLess @ назначение у ++ одно. Логически увеличивать экземпляр класса на логическую единицу тчк. Если ++ дает мне любого рода специфику, которая не дает мне возможности использовать его также как ++ для int - а, то на кой черт он нужен?? Во-первых, с чего ты взял, что это логическое увеличение должно быть столь же тривиально, как у int? Кроме как в арифметике ++ больше нигде нельзя использовать? Во-вторых, даже по части арифметики не всё так гладко. Пусть имеется класс для работы с заоблачно большими числами. Память под число выделяется динамически (скажем, при помощи new). Когда число каким-то образом увеличивают, у него могут появиться новые разряды, под которые надо выделять доп. память. Выделение памяти – это уже своего рода специфика. Так что, теперь всё в функциях-членах считать? Пример так себе, но, думаю, суть ясна. |
Сообщ.
#53
,
|
|
|
Цитата Unreal Man @ Во-первых, с чего ты взял, что это логическое увеличение должно быть столь же тривиально, как у int? Кроме как в арифметике ++ больше нигде нельзя использовать? Ты вообще читаешь или делаешь выводы по первым трем буквам? вчитываемся.. Цитата Логически увеличивать экземпляр класса на логическую единицу тчк. А теперь отвечаем. причем тут арифметика? |
Сообщ.
#54
,
|
|
|
Цитата LuckLess @ А теперь отвечаем. причем тут арифметика? А где ещё прокатит это твоё сравнение с int? |
Сообщ.
#55
,
|
|
|
Цитата Unreal Man @ А где ещё прокатит это твоё сравнение с int? везде, где можно выделить операцию логического присваения и логическую единицу. |
Сообщ.
#56
,
|
|
|
Цитата LuckLess @ Если ++ дает мне любого рода специфику, которая не дает мне возможности использовать его также как ++ для int - а, то на кой черт он нужен?? Если речь шла о возможности составления сложных выражений, то специфика не обязательно будет её исключать. Однако знать о специфике (или её возможном присутствии) всё равно желательно. |
Сообщ.
#57
,
|
|
|
Цитата Unreal Man @ Однако знать о специфике (или её возможном присутствии) всё равно желательно. Т.е. с помощью ++i, а не i++ ты хочешь указать, что инкремент делается для объекта, отличного от встроенного типа, я тебя правильно понял? |
Сообщ.
#58
,
|
|
|
Да :-) При беглом просмотре программы это будет своего рода подсказкой. Ведь когда видишь в гуще кода что-то вроде ++Name мысль в первую очередь возникает о каком-нибудь встроенном типе (ибо это самый распространённый вариант). Пока не увидишь определения, иногда и не поймёшь, что перед тобой возникло (если код уже давний и ты не помнишь деталей). Насчёт возможности во всех ситуациях строго разганичивать использование формы инкрементов по данному принципу я в общем-то не особо уверен (уже предвижу каверзные контрпримеры :-) ). Сам я таким разграничением не пользовался – просто выдвигаю его как вариант на всеобщую критику :-)
|
Сообщ.
#59
,
|
|
|
Цитата Unreal Man @ Да :-) Т.е., специфику (объект невстроенного типа) в инкременте ты показать хочешь (кстати, а если результат инкремента должен использоваться в выражении, например: i++ + k - как ты собираешься указывать специфику? ![]() Как насчет других операций? Например, m = i ? Здесь ведь тоже есть специфика - встроенный тип зачастую memcpy делает, пользовательский - фиг его знает. Сложно жить без возможности и тут указать специфику? ![]() Предлагаю тебе юзать на выбор один из способов: 1. Отказаться от перегрузки операторов. Знай себе пиши: i.VerySpecificIncrement(); m.VerySpecificAssigment(i) и т.д. "При беглом просмотре программы это будет " суперподсказкой о специфике, мимо которой не пройдешь. 2. Оставь перегрузку, но используй элемент венгерской нотации: помечай объекты всех невстроенных типов специальным префиксом. Тогда всегда будешь знать про специфику в выражениях: ++oi; om = oi; и т.п. По сути, то, что ты предлагаешь - аналог такой нотации, просто выраженный не в названиях переменных, а в использовании/неиспользовании отдельных языковых конструкций. Но думаю, поклонников твоей нотации гораздо меньше, чем поклонников венгерской. ![]() |
Сообщ.
#60
,
|
|
|
Цитата Hryak @ Т.е., специфику (объект невстроенного типа) в инкременте ты показать хочешь Всего лишь её возможное наличие, если точнее. Цитата Hryak @ кстати, а если результат инкремента должен использоваться в выражении, например: i++ + k - как ты собираешься указывать специфику? Цитата Hryak @ Как насчет других операций? Эк куда тебя погнало-то :-) Ну, ясное дело, что никак. Цитата Hryak @ Предлагаю тебе юзать на выбор один из способов: Ты не поверишь, но о них я уже думал :-) Цитата Hryak @ Знай себе пиши: i.VerySpecificIncrement(); m.VerySpecificAssigment(i) и т.д. Громоздко, однако. Очень громоздко. Цитата Hryak @ Оставь перегрузку, но используй элемент венгерской нотации Тоже удлинение имени :-) Венгерскую нотацию использую в основном лишь для булевых переменных и указателей. Может, с помощью регистра начальной буквы их различать? |
Сообщ.
#61
,
|
|
|
Цитата Unreal Man @ Эк куда тебя погнало-то :-) Ну, ясное дело, что никак. Ясно, что никак. Но ведь тебе хотелось бы? Цитата Громоздко, однако. Очень громоздко. Названия я для примера привел. Можно и покороче обозвать - все равно вызов фукнции не будет смахивать на использование оператора - обозначение возможной специфики не пропадет. ![]() ![]() Цитата Тоже удлинение имени :-) На одну букву? Это не довод. Одна буква, а показывает возможную специфику в любом контексте использования объекта. То, что ты предложил - это половинчатое(даже не половинчатое, а 1/xx) решение, т.к. охватывает только два оператора из десятков возможных, и то, не всегда применимое. Цитата Может, с помощью регистра начальной буквы их различать? Ну, если в твоем naming convention заглавная буква ничего еще не означает (ни верблюдов, ни прочих животных не наблюдается) - различай так. |
Сообщ.
#62
,
|
|
|
Цитата antigen @ А другой результат тут трудно ожидать. Инкремент/декремент адреса легко оптимизируем и весьма быстр, не думаю, что в этом кто-то сомневается. Ты попробуй какой-нибудь тип, например, длинной арифметики поинкрементировать/декрементировать.Результаты экспериментов: (желающие могут повторить, возможно, у кого-то получатся иные) А отсюда и такие выводы. Добавлено Хотя бы такую функцию: ![]() ![]() 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; } |
Сообщ.
#63
,
|
|
|
Цитата 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 – это уже возможная специфика. Хотя в случае со счётчиком это вряд ли... |
Сообщ.
#64
,
|
|
|
Цитата Unreal Man @ Ты не темни, прямо скажи, какой вариант использовать? Неизвестный тип T – это уже возможная специфика. ![]() А чтобы шаблон не смущал можно написать так: ![]() ![]() #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; } ![]() ![]() #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 ) |
Сообщ.
#65
,
|
|
|
Цитата Unreal Man @ Да :-) При беглом просмотре программы это будет своего рода подсказкой. Ведь когда видишь в гуще кода что-то вроде ++Name мысль в первую очередь возникает о каком-нибудь встроенном типе (ибо это самый распространённый вариант). Пока не увидишь определения, иногда и не поймёшь, что перед тобой возникло (если код уже давний и ты не помнишь деталей). Ты уж извини, но это ахинея редкостная. Тут даже и критиковать нечего. Если просматривая код ты не понимаешь, что перед тобой "возникает", то тут никакие подсказки не помогут. Ну и вообще использовать инкремент в качестве подскаки о типе... ![]() ![]() Могу подкинуть идею: если у тебя большой участок кода будет без инкрементов, то ты делай такие вставочки ![]() ![]() val++; val--; // а это чтобы значение не изменилось А то вдруг забудешь какой там тип встроенный или нет ![]() |
Сообщ.
#66
,
|
|
|
Цитата trainer @ Ты не темни, прямо скажи, какой вариант использовать? Если считаешь возможным определение counter_type в виде пользовательского типа, то префиксный. Если же нет – постфиксный (тем самым ты только подчеркнёшь, что под этим загадочным counter_type скрывается именно какой-то элементарный тип). Цитата trainer @ ++i или i++ надлежит писать? Как обозначить специфику? Ещё раз: речь идёт об обозначении возможного наличия специфики. Цитата Alex437 @ Если просматривая код ты не понимаешь, что перед тобой "возникает", то тут никакие подсказки не помогут. Речь идёт о том, сколько кода тебе нужно просмотреть, и сколько времени у тебя уйдёт на то, чтобы это понять. Цитата Alex437 @ Ну и вообще использовать инкремент в качестве подскаки о типе... А что, когда ты видишь в коде ++, у тебя никаких мыслей по поводу типа объекта не возникает? Инкремент сам по себе уже является определённой подсказкой о типе. Здесь лишь добавляется дополнительная информация. Цитата Alex437 @ Могу подкинуть идею: если у тебя большой участок кода будет без инкрементов, то ты делай такие вставочки Типо смешно. Речь-то идёт скорее о том, что при виде ++ легко ввести себя в заблуждение, приняв объект за переменную встроенного типа (поскольку в большинстве случаев, когда видишь подобный кусок кода, это действительно так). Использование свободной префиксной формы может выступать в роли подсказки о том, что это впечатление вероятно может оказаться ошибочным. |
Сообщ.
#67
,
|
|
|
Unreal Man
Угу. Есть уже способ чтобы обозначить тип. 2 таких способа не нужно. Чем больше, тем хуже в данном случае. Если когда ты видиш ++ у тебя возникает задняя мысль поп оводу типа объекта..то хух.. это по крайней мере странно. О типе должен говорить ИДЕНТИФИКАТОР и только он. Такого рода использование ++ и -- идет в ущерб расширяемости и гибкости, к томуже вносит лишнюю и ненужную информацию, которую должен помнить программист. |
Сообщ.
#68
,
|
|
|
Цитата Unreal Man @ Я считаю возможным определение любого типа как пользовательского. Причем сейчас я не знаю, что потребуется через месяц. А ты - не считаешь?Если считаешь возможным определение counter_type в виде пользовательского типа, то префиксный. Цитата Unreal Man @ Для меня это звучит примерно как "наполовину беременна". Наличие специфики всегда возможно.Ещё раз: речь идёт об обозначении возможного наличия специфики. Цитата Unreal Man @ А какие мысли должны возникать? Ну если только "откомпилируется или нет?" Мне все время казалось, что типы созданы для того, чтобы не задумываться о том, как они устроены. А что, когда ты видишь в коде ++, у тебя никаких мыслей по поводу типа объекта не возникает? |
Сообщ.
#69
,
|
|
|
Цитата Unreal Man @ А что, когда ты видишь в коде ++, у тебя никаких мыслей по поводу типа объекта не возникает? Нет, не возникает. Обычно тип объекта я определяю несколько иными способами. И мне всегда надо знать точный тип объекта, а не просто видеть встроенный он или нет. А у тебя получается, что ты не знаешь тип объекта и следовательно не знаешь его роль в программе. Но видишь, что он инкрементируется и начинаешь предполагать, что вероятно он пользовательского типа... Так? А что это за объект и зачем он инкрементируется - это наверно долго и скучно разбираться? ![]() Извини, но мне это и вправду забавным кажется... Я собственно даже не пойму, ты всерьез это пишешь или издеваешься? |
Сообщ.
#70
,
|
|
|
Страуструп, издание за 98г, стр 629.
Отметим, что пост-инкремент используе промежуточную переменную, а пре-инкремент нет. По это причине, для итераторов предпочтительнее ++p, а не p++. |
Сообщ.
#71
,
|
|
|
Цитата trainer @ Цитата (Unreal Man @ 8.06.06, 11:52) Если считаешь возможным определение counter_type в виде пользовательского типа, то префиксный. Я считаю возможным определение любого типа как пользовательского. Причем сейчас я не знаю, что потребуется через месяц. А ты - не считаешь? ![]() |