Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] Выражения с инкремента? (http://forum.oszone.net/showthread.php?t=259245)

alex-dogg 23-04-2013 15:28 2138292

Выражения с инкремента?
 
Есть выражения с инкремент
выражение 1:
Код:

int a = 2, c = 0;
c = (++a) +++a;

c = 6. ?
а = 4
--------------
выражение 2:
Код:

int a = 2, c = 0;
c = ++a+(++a);

c = 8. ?
a = 4.
-----------
Я не могу понять почему компилятор дает такой ответ. (Visual Studio 2005).

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

deviance 23-04-2013 16:39 2138351

alex-dogg,
Чудеса кодогенерации

Это результат дизассемблирования двух выражений:
1. c = (++a)+++a;
Код:

mov    [ebp+a], 2      ; Инициализируем локальные переменные. a = 2;
mov    [ebp+c], 0      ; c = 0;
mov    eax, [ebp+a]    ; Кладем значение локальной переменной `a` в eax
add    eax, 1          ; Инкремент ( eax == 3 )
mov    [ebp+a], eax    ; Сохраняем полученное eax в `а` ( а == 3 )
mov    ecx, [ebp+a]    ; В есх кладем значение а ..
add    ecx, [ebp+a]    ; и складываем с самим собой.
mov    [ebp+c], ecx    ; Сохраняем полученное значение в переменную `с`
mov    edx, [ebp+a]    ; А вот это еще один инкремент `а`
add    edx, 1          ; ..
mov    [ebp+a], edx    ; ..
                        ; Но `а` уже не используется в вычислении `с`. Это мертвый код.
mov    esi, esp
mov    eax, [ebp+c]
push    eax
mov    ecx, [ebp+a]
push    ecx
push    offset Format  ; "a=%d c=%d\n"
call    ds:printf      ; На консоли будет показано: a=4 c=6

2. c = ++a+(++a);
Код:

mov    [ebp+a], 2      ; a = 2;
mov    [ebp+c], 0      ; c = 0;
mov    eax, [ebp+a]    ; eax = a;
add    eax, 1          ; Инкремент `a`
mov    [ebp+a], eax    ; a == 3
mov    ecx, [ebp+a]    ;
add    ecx, 1          ; Еще один инкремент `a`
mov    [ebp+a], ecx    ; а == 4
mov    edx, [ebp+a]    ;
add    edx, [ebp+a]    ; Сложение двух `a`
mov    [ebp+c], edx    ; с == 8
mov    esi, esp        ;
mov    eax, [ebp+c]    ;
push    eax
mov    ecx, [ebp+a]
push    ecx
push    offset Format  ; "a=%d c=%d\n"
call    ds:printf      ; На консоли будет показано: a=4 c=8



Время: 19:49.

Время: 19:49.
© OSzone.net 2001-