crossplatform.ru

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

4 страниц V  < 1 2 3 4 >  
Ответить в данную темуНачать новую тему
> i++ против ++i, спор однако
Red Devil
  опции профиля:
сообщение 21.7.2008, 16:54
Сообщение #11


Студент
*

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

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




Репутация:   3  


Цитата
if (++i > k)
goto 1branch
else
goto 2branch
Language: cpp


if (i++ > k)
goto 1branch
else
goto 2branch

Этот пример не удачный, т.к. тут выполняются разные по семантике задачи.


Цитата(Litkevich Yuriy @ 21.7.2008, 11:43) *
я говорил о вменяемом компиляторе, но не бесплатном, в IAR разницы ни какой, я давно про эту особенность Си прочитал, и смотрел результат работы разных компиллеров. в HiTech и IAR нет разницы, просто люди умеют писать оптимизирующие копиллеры. А GNU это бесплатный компиллер, с минимально возможной оптимизацией, как там прочие поживают не в курсе.

Так я про это и говорю, что для GNU компилеров делается и это нужно учитывать.

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

Для итераторов есть и очень существенная, при случае скажи об этом вашем программистам и еще книги посоветуй им почитать про стандартную библиотеку, раз таких основ не знают. Могут так же посмотреть исходные коды STL и подумать, почему там написано так и именно так, и никак иначе.
Вот пример, как генерируется код для типов, у которых определены собственные инкрементные операторы ++ (и для итераторов тоже, вне зависимости от компилятора).
Вот такой код генерируются для ++a; (69 строк)
    .file    "main.cpp"
    .text
    .align 2
.globl main
    .type    main, @function
main:
.LFB8:
    pushl    %ebp
.LCFI0:
    movl    %esp, %ebp
.LCFI1:
    subl    $8, %esp
.LCFI2:
    andl    $-16, %esp
    movl    $0, %eax
    subl    %eax, %esp
    subl    $8, %esp
    pushl    $0
    leal    -4(%ebp), %eax
    pushl    %eax
.LCFI3:
    call    _ZN1AC1Ei
    addl    $16, %esp
    subl    $12, %esp
    leal    -4(%ebp), %eax
    pushl    %eax
    call    _ZN1AppEv
    addl    $16, %esp
    movl    $0, %eax
    leave
    ret
.LFE8:
    .size    main, .-main
    .section    .gnu.linkonce.t._ZN1AC1Ei,"ax",@progbits
    .align 2
    .weak    _ZN1AC1Ei
    .type    _ZN1AC1Ei, @function
_ZN1AC1Ei:
.LFB9:
    pushl    %ebp
.LCFI4:
    movl    %esp, %ebp
.LCFI5:
    movl    8(%ebp), %edx
    movl    12(%ebp), %eax
    movl    %eax, (%edx)
    popl    %ebp
    ret
.LFE9:
    .size    _ZN1AC1Ei, .-_ZN1AC1Ei
    .section    .gnu.linkonce.t._ZN1AppEv,"ax",@progbits
    .align 2
    .weak    _ZN1AppEv
    .type    _ZN1AppEv, @function
_ZN1AppEv:
.LFB10:
    pushl    %ebp
.LCFI6:
    movl    %esp, %ebp
.LCFI7:
    movl    8(%ebp), %eax
    incl    (%eax)
    movl    8(%ebp), %eax
    popl    %ebp
    ret
.LFE10:
    .size    _ZN1AppEv, .-_ZN1AppEv
    .section    .note.GNU-stack,"",@progbits
    .ident    "GCC: (GNU) 3.3.4"


А вот такой код для a++ (101 строка)
    .file    "main.cpp"
    .text
    .align 2
.globl main
    .type    main, @function
main:
.LFB8:
    pushl    %ebp
.LCFI0:
    movl    %esp, %ebp
.LCFI1:
    subl    $8, %esp
.LCFI2:
    andl    $-16, %esp
    movl    $0, %eax
    subl    %eax, %esp
    subl    $8, %esp
    pushl    $0
    leal    -4(%ebp), %eax
    pushl    %eax
.LCFI3:
    call    _ZN1AC1Ei
    addl    $16, %esp
    leal    -8(%ebp), %edx
    subl    $4, %esp
    pushl    $0
    leal    -4(%ebp), %eax
    pushl    %eax
    pushl    %edx
    call    _ZN1AppEi
    addl    $12, %esp
    movl    $0, %eax
    leave
    ret
.LFE8:
    .size    main, .-main
    .section    .gnu.linkonce.t._ZN1AC1Ei,"ax",@progbits
    .align 2
    .weak    _ZN1AC1Ei
    .type    _ZN1AC1Ei, @function
_ZN1AC1Ei:
.LFB9:
    pushl    %ebp
.LCFI4:
    movl    %esp, %ebp
.LCFI5:
    movl    8(%ebp), %edx
    movl    12(%ebp), %eax
    movl    %eax, (%edx)
    popl    %ebp
    ret
.LFE9:
    .size    _ZN1AC1Ei, .-_ZN1AC1Ei
    .section    .gnu.linkonce.t._ZN1AppEi,"ax",@progbits
    .align 2
    .weak    _ZN1AppEi
    .type    _ZN1AppEi, @function
_ZN1AppEi:
.LFB10:
    pushl    %ebp
.LCFI6:
    movl    %esp, %ebp
.LCFI7:
    pushl    %ebx
.LCFI8:
    subl    $4, %esp
.LCFI9:
    movl    8(%ebp), %ebx
    movl    12(%ebp), %eax
    movl    (%eax), %eax
    movl    %eax, (%ebx)
    subl    $12, %esp
    pushl    12(%ebp)
.LCFI10:
    call    _ZN1AppEv
    addl    $16, %esp
    movl    %ebx, %eax
    movl    -4(%ebp), %ebx
    leave
    ret    $4
.LFE10:
    .size    _ZN1AppEi, .-_ZN1AppEi
    .section    .gnu.linkonce.t._ZN1AppEv,"ax",@progbits
    .align 2
    .weak    _ZN1AppEv
    .type    _ZN1AppEv, @function
_ZN1AppEv:
.LFB11:
    pushl    %ebp
.LCFI11:
    movl    %esp, %ebp
.LCFI12:
    movl    8(%ebp), %eax
    incl    (%eax)
    movl    8(%ebp), %eax
    popl    %ebp
    ret
.LFE11:
    .size    _ZN1AppEv, .-_ZN1AppEv
    .section    .note.GNU-stack,"",@progbits
    .ident    "GCC: (GNU) 3.3.4"


Вот код на С++, который тестировался :
class A
{
public:
    A(int val) : m_val(val) {}
    A & operator ++ ()    
    {
    ++m_val;
    return *this;
    }
    
    A operator ++(int)
    {
    A temp(*this);
    ++*this;
    return temp;
    }
    
    int m_val;
};

int main()
{
    A a(0);
    
    a++;
    //++a;
    
    return 0;
}


Сообщение отредактировал Red Devil - 21.7.2008, 16:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 21.7.2008, 18:14
Сообщение #12


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

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

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




Репутация:   17  


Цитата
Для итераторов есть и очень существенная, при случае скажи об этом вашем программистам и еще книги посоветуй им почитать про стандартную библиотеку, раз таких основ не знают. Могут так же посмотреть исходные коды STL и подумать, почему там написано так и именно так, и никак иначе.

Приколист, однако! :) Вообще-то они и проверяли. STL во встроенном ПО не используется в целях надежности. Для современных компиляторов эта разница по барабану. А стандартные итераторы, как я их понял, это далеко не те, что в stl!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
void*
  опции профиля:
сообщение 21.7.2008, 18:43
Сообщение #13


Программист-самоучка
***

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

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




Репутация:   3  


Цитата(AD @ 21.7.2008, 18:14) *
STL во встроенном ПО не используется в целях надежности.

прикольно однако. Ты считаешь STL ненадежной? :)
Цитата(AD @ 21.7.2008, 18:14) *
А стандартные итераторы, как я их понял, это далеко не те, что в stl!

еще прикольней :) и чем же они так сильно отличаются?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 21.7.2008, 19:40
Сообщение #14


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

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

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




Репутация:   17  


Цитата(void* @ 21.7.2008, 19:43) *
прикольно однако. Ты считаешь STL ненадежной? :)
Цитата(AD @ 21.7.2008, 18:14) *
А стандартные итераторы, как я их понял, это далеко не те, что в stl!

еще прикольней :) и чем же они так сильно отличаются?

На 1 вопрос ответ: не я так считаю, а таково требование к встроенному софту - stl не использовать!
На 2 вопрос: я точно ответить не смогу. Я знаю, что в stl используют динамическую память, что как-раз и не нравится, и чего и боятся при использовании во встроенном софте. Самолет или вертолет не должен в пути отказать! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 21.7.2008, 19:42
Сообщение #15


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

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

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




Репутация:   94  


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

тотже принтф съедает около 1.5кило памяти программ, сильно накладно. а стандартные итераторы в С++ помоему это как раз и есть STL.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 21.7.2008, 19:44
Сообщение #16


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

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

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




Репутация:   17  


Цитата(Litkevich Yuriy @ 21.7.2008, 20:42) *
во встроенном ПО стандартных библиотек избегают по причине того что редкий Си компиллер будет компилить только те функции которые нужны, он сунет в бинарь все без разбора.

Из-за этого тоже. Но первопричина - как раз динамическая память! Ее боятся, а в stl она повсюду используется! ;)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 21.7.2008, 19:51
Сообщение #17


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

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

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




Репутация:   94  


Цитата(AD @ 21.7.2008, 23:44) *
Ее боятся

Просто скушает много во время работы, в этом-то и касяк, когда руками выделяешь ты всегда видишь сколько.
Я масив выделял, а потом по его адресу размещал динамические переменные, при крайней нужде.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Novak
  опции профиля:
сообщение 22.7.2008, 5:25
Сообщение #18


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

Группа: Участник
Сообщений: 319
Регистрация: 15.3.2008
Из: Замкадыш
Пользователь №: 121

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




Репутация:   6  


Цитата(Red Devil @ 21.7.2008, 17:54) *
Этот пример не удачный, т.к. тут выполняются разные по семантике задачи.

Эээ.. Ну, а при равных по семантике задачах, например
for (int i=0; ...; i++)
for (int i=0; ...; ++i)

Нормальный компилятор и не должен в итоге делать различий между инкрементной и декрементной формами.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
void*
  опции профиля:
сообщение 22.7.2008, 9:05
Сообщение #19


Программист-самоучка
***

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

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




Репутация:   3  


Цитата(Novak @ 22.7.2008, 5:25) *
Нормальный компилятор и не должен в итоге делать различий между инкрементной и декрементной формами.

а для чего тогда по-твоему вообще создавали две формы этого оператора? чтобы компилятор не делал между ними различий? есть ситуации, в которых предпочтительнее одна форма, есть в которых предпочтительнее другая, но они не должны быть одинаково восприняты компилятором, иначе исчезает весь их смысл
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Red Devil
  опции профиля:
сообщение 22.7.2008, 13:56
Сообщение #20


Студент
*

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

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




Репутация:   3  


Цитата(Novak @ 22.7.2008, 5:25) *
Нормальный компилятор и не должен в итоге делать различий между инкрементной и декрементной формами.

Согласен, для простых типов современные компиляторы нормально отработают.
Когда же операторы ++ определены программистом (а это обычно итераторы) - компилятор не знает разницы, может программист по своему реализовал оператор ++ и у них асболютно разная логика, поэтому он ничего не будет оптимизировать.
Поэтому писать ++i нужно вводить в привычку, и это является хорошем тоном/стилем в программировании на С++.
Мне во всяком случае достаточно посмотреть как реализован цикл for, чтобы определить базовые навыки программиста.

Сообщение отредактировал Red Devil - 22.7.2008, 13:58
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 14.1.2025, 20:57