Войти

Показать полную графическую версию : [решено] Выражения с инкремента?


alex-dogg
23-04-2013, 15:28
Есть выражения с инкремент
выражение 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
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




© OSzone.net 2001-2012