crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

4 страниц V  < 1 2 3 4 >  
Ответить в данную темуНачать новую тему
> i++ против ++i, спор однако
Andrew Selivanov
  опции профиля:
сообщение 22.7.2008, 15:09
Сообщение #21


Участник
**

Группа: Участник
Сообщений: 249
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 3

Спасибо сказали: 15 раз(а)




Репутация:   6  


Рискуя нарваться на крики негодования, но все же:
Инженерный подход: так, оно должно нормально работать по алгоритму M, доделаю, нужно будет еще модули X, Y, Z
Программистский подход: как же мне написать, ++i или i++? как будет быстрее?.. я выиграю 0,01мс/3 байта или нет? (спустя три часа) дада, да, я понял, ++i гораздо лучше, i++ нужно нахрен убрать из языка!
8)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.7.2008, 15:14
Сообщение #22


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


:)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 22.7.2008, 15:25
Сообщение #23


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Andrew Selivanov, логично! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 22.7.2008, 21:25
Сообщение #24


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Не совсем так. Для твоего примера, нормальный современный компилятор, сообразит, что возвращаемое значение не используется - значит его можно выкинуть. Естественно, это в случае, когда включена хоть какая-то оптимизация.
struct A {
  A() : m_val(0) {}
  A(int val) : m_val(val) {}
  A & operator ++ () {
    ++m_val;
    return *this;
  }
  
  A operator ++(int) {
    A temp(*this);
    ++*this;
    return temp;
  }
  bool operator ==(const A& x) {
    return m_val == x.m_val;
  }
  bool operator !=(const A& x) {
    return m_val != x.m_val;
  }

  private:  
    int m_val;
};

int f1(A cur, const A& end) {
  int r = 0;
  for (; cur != end; ++cur)
    ++r;
  return r;
}

int f2(A cur, const A& end) {
  int r = 0;
  for (; cur != end; cur++)
    ++r;
  return r;
}

g++ (GCC) 3.4.5 (mingw-vista special r3)
>g++ -S -O1 iter.cpp
    .file    "iter.cpp"
    .text
    .align 2
.globl __Z2f11ARKS_
    .def    __Z2f11ARKS_;    .scl    2;    .type    32;    .endef
__Z2f11ARKS_:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ebx
    movl    12(%ebp), %ebx
    movl    $0, %ecx
    movl    8(%ebp), %eax
    movl    %eax, %edx
    cmpl    (%ebx), %eax
    je    L9
L7:
    incl    %ecx
    leal    1(%edx), %eax
    movl    %eax, %edx
    cmpl    (%ebx), %eax
    jne    L7
    movl    %eax, 8(%ebp)
L9:
    movl    %ecx, %eax
    popl    %ebx
    popl    %ebp
    ret
    .align 2
.globl __Z2f21ARKS_
    .def    __Z2f21ARKS_;    .scl    2;    .type    32;    .endef
__Z2f21ARKS_:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ebx
    movl    12(%ebp), %ebx
    movl    $0, %ecx
    movl    8(%ebp), %eax
    movl    %eax, %edx
    cmpl    (%ebx), %eax
    je    L20
L18:
    incl    %ecx
    leal    1(%edx), %eax
    movl    %eax, %edx
    cmpl    (%ebx), %eax
    jne    L18
    movl    %eax, 8(%ebp)
L20:
    movl    %ecx, %eax
    popl    %ebx
    popl    %ebp
    ret

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

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

Сообщение отредактировал Tonal - 22.7.2008, 21:29
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Red Devil
  опции профиля:
сообщение 23.7.2008, 7:34
Сообщение #25


Студент
*

Группа: Участник
Сообщений: 68
Регистрация: 6.6.2008
Из: Saint-Petersburg
Пользователь №: 194

Спасибо сказали: 1 раз(а)




Репутация:   3  


Цитата(Andrew Selivanov @ 22.7.2008, 16:09) *
Рискуя нарваться на крики негодования, но все же:
Инженерный подход: так, оно должно нормально работать по алгоритму M, доделаю, нужно будет еще модули X, Y, Z
Программистский подход: как же мне написать, ++i или i++? как будет быстрее?.. я выиграю 0,01мс/3 байта или нет? (спустя три часа) дада, да, я понял, ++i гораздо лучше, i++ нужно нахрен убрать из языка!

Это отличиает программиста от не программиста.
И если ты не знаешь таких базовых понятий, что любая операция в цикле дорогостоящая - говорить вообще не о чем. Программист вообще от думать не должен, в цикле всегда должен быть оператор ++i.

Цитата(AD @ 22.7.2008, 16:25) *
Не совсем так. Для твоего примера, нормальный современный компилятор, сообразит, что возвращаемое значение не используется - значит его можно выкинуть. Естественно, это в случае, когда включена хоть какая-то оптимизация.

Цитата(Red Devil @ 22.7.2008, 14:56) *
Когда же операторы ++ определены программистом (а это обычно итераторы) - компилятор не знает разницы, может программист по своему реализовал оператор ++ и у них асболютно разная логика, поэтому он ничего не может оптимизировать.

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

Сообщение отредактировал Red Devil - 23.7.2008, 7:38
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ЙаМайскЫйПчОЛ
  опции профиля:
сообщение 23.7.2008, 9:16
Сообщение #26


Участник
**

Группа: Участник
Сообщений: 154
Регистрация: 10.7.2008
Из: СПб
Пользователь №: 232

Спасибо сказали: 7 раз(а)




Репутация:   5  


Посвящается вечному спору)
Инкремент постфиксный(i++) и (++i)префиксный нужны языку программирования такому как С++, ибо он не ++С )))
Это две функции которые выполняют, одно и тоже только в разное время, гибкость которая появляется в языке с введением двух, казалось бы одинаковых функций, но работающих слегка различно, постоянно приводит к спору о неоднозначности интерпретированния таких записей и как следствие к различным реализациям в алгоритмах компиляторов на соответствующие постфиксные и префиксные операции.

Значение ++x будет новое(увеличенное) значение x, т.е y=++x => y=(x+=1). Напротив, значением x++ является старое значение x, т.е. y=x++ => y=(t=x,x+=1,t) тип t такойже как и x.

по поводу
Цитата(Red Devil @ 23.7.2008, 8:34) *
Это отличиает программиста от не программиста.
И если ты не знаешь таких базовых понятий, что любая операция в цикле дорогостоящая - говорить вообще не о чем. Программист вообще от думать не должен, в цикле всегда должен быть оператор ++i.


Страуструп в одном из примеров:

int length = strlen(q);
for(int i=0; i<=length; i++) p[i]=q[i]

))))
и циклы while с указателями реализует также.
Я тут полистал => Он вообще в операции циклов отдает предпочтение постфиксной записи.

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

Цитата(AD @ 21.7.2008, 12:01) *
Для целочисленного типа и простых итераторах для современных компиляторов разницы не будет, насколько я знаю от программистов, которые делают встроенное ПО для авиации! smile.gif Я еще только учусь на такого программиста, но встроенное ПО пока что не доверяют.


Надо отличать ОСРВ(ОС Реального времени, типа QNX), от OC, правило звучит так: Если кодишь под ОСРВ - кодь на Си и в статике, если кодишь под ОС, пользуй блага С++ )

Сообщение отредактировал ЙаМайскЫйПчОЛ - 23.7.2008, 9:03
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 23.7.2008, 9:39
Сообщение #27


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(ЙаМайскЫйПчОЛ @ 23.7.2008, 10:16) *
Не путайте реализацию-интерпретации-понимания-функциональности-операции конкретным кодером в конкретном компилере и изначальную идею потенциального-увеличения-однозначности-визуальной-интерпретации-операции-и-локаничности-записи.

:blink:
А можно по-русски или по рабоче-крестьянски? :)
Цитата
Надо отличать ОСРВ(ОС Реального времени, типа QNX), от OC, правило звучит так: Если кодишь под ОСРВ - кодь на Си и в статике, если кодишь под ОС, пользуй блага С++ )

Про статику согласен абсолютно. А вот на счет С/С++: для того, чтобы код был более понятен и структурирован, а также для множества других удобств, которые предоставляет С++, мы используем С++ именно для приложений на бортовых приборах. Предельные участки и код, который работает жестко от железа, естественно, пишется на С. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ЙаМайскЫйПчОЛ
  опции профиля:
сообщение 23.7.2008, 9:59
Сообщение #28


Участник
**

Группа: Участник
Сообщений: 154
Регистрация: 10.7.2008
Из: СПб
Пользователь №: 232

Спасибо сказали: 7 раз(а)




Репутация:   5  


Цитата(AD @ 23.7.2008, 10:39) *
Про статику согласен абсолютно. А вот на счет С/С++: для того, чтобы код был более понятен и структурирован, а также для множества других удобств, которые предоставляет С++, мы используем С++ именно для приложений на бортовых приборах. Предельные участки и код, который работает жестко от железа, естественно, пишется на С. smile.gif


С++ в статике, без ООП, мне кажется, это и есть Си. Но не мне судить о преимуществах.

Цитата(ЙаМайскЫйПчОЛ @ 23.7.2008, 10:16) *
Не путайте реализацию-интерпретации-понимания-функциональности-операции конкретным кодером в конкретном компилере и изначальную идею потенциального-увеличения-однозначности-визуальной-интерпретации-операции-и-локаничности-записи.


разделение операции на постфиксную и префиксную должны были сделать код более наглядным и локаничным, подразумевая под собой возможность компилятора оптимизировать инкремент в том числе с помощью битового сдвига, и изначально предпологались не больше не меньше, а как механизм увеличения на 1 у.е. (это мое мнение) но с разными возвращаемыми значениями. При проектировании учитывалась возможность перегрузки операторов, а так как инкремент тоже оператор => перегрузили и его, что привело к удобной и оптимизированной работе с указателями и как следствие итераторами.
Но частично, оптимизация в реализации и функциональность была не использована при создании компиляторов из-за многих неоднозначностей возникающих при использовании этих операций. Сколько компиляторов, столько и алгоритмов оптимизации кода.

Сообщение отредактировал ЙаМайскЫйПчОЛ - 23.7.2008, 10:16
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 23.7.2008, 10:13
Сообщение #29


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(ЙаМайскЫйПчОЛ @ 23.7.2008, 10:59) *
С++ в статике, без ООП, мне кажется, это и есть Си. Но не мне судить о преимуществах.

ну... что-то переборщили

Где есть и возможность (а иногда и необходимость), там используются и наследование, и полиморфизм, и инкапсуляция. Ладно, в общем-то уяснили все! ;) :)

А за разъяснение спасибо!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 23.7.2008, 11:10
Сообщение #30


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Цитата(Red Devil @ 23.7.2008, 11:34) *
Цитата
Не совсем так. Для твоего примера, нормальный современный компилятор, сообразит, что возвращаемое значение не используется - значит его можно выкинуть. Естественно, это в случае, когда включена хоть какая-то оптимизация.

Цитата(Red Devil @ 22.7.2008, 14:56) *
Когда же операторы ++ определены программистом (а это обычно итераторы) - компилятор не знает разницы, может программист по своему реализовал оператор ++ и у них асболютно разная логика, поэтому он ничего не может оптимизировать.

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

Я же привёл плюсовый код с совмещением (перегрузкой) инкремента, и асмовый листинг.
Покажи, пожалуйста, код, в функции f2 (в асме __Z2f21ARKS_), который отвечает за создание неиспользуемого экземпляра и его возврат.
Его нет.
Дело в том, что если у действия нет побочных эффектов, и его результат нигде не используется, его можно смело выкидывать из программы. Именно это и делает оптимизатор. Причём там всё ещё несколько сложнее, т.к. оптимизатор работает не с языковыми конструкциями, не с деревом разбора, а работает он с промежуточным объектным кодом, на уровне которого уже никакого С++ или там Ada нет - есть инструкции некоторой универсальной машины, которые потом, после оптимизации, преобразуются в объектный код.
Почитай например "Красного дракона" (Ахо А., Сети Р., Ульман Дж. Компиляторы. Принципы, технологии, инструменты)
Там всё это подробно изложено. :)

Это не агитация за то, чтобы убрать постинкремет из языка.
Я довольно хорошо понимаю разницу между этими операторами, и сам всегда пишу for (...; ++i).
Просто не нужно создавать мифы и догмы, нужно аккуратно пользоваться доступным инструментарием. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

4 страниц V  < 1 2 3 4 >
Ответить в данную темуНачать новую тему
Теги
Нет тегов для показа


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




RSS Текстовая версия Сейчас: 28.12.2024, 10:37