| # | 사용자의 핵심 질문 | 답변 핵심 요약 |
|---|---|---|
| 1 | 전위는 ‘실행 전’에 1 증가, 후위는 ‘실행 후’에 1 증가.컴파일러는 그 ‘전/후’를 어떻게 구분하나? | 파서 단계에서 별도 문법 규칙(prefix vs postfix)을 인식 → AST에 PreIncExpr/PostIncExpr로 분리. 각 노드가 ‘증가 시점’과 ‘결과값’을 명시한다. |
| 2 | AST 단계에서 보이는 tmp, val은 실제로 어디 저장되나? | 주로 레지스터(빈 슬롯 없으면 스택) 사용. tmp는 새로운 i 값, val은 표현식 결과를 담는다. |
| 3 | 전위(++i)에서 왜 val = tmp가 또 필요한가? | 전위 결과가 증가된 값이기 때문. val과 tmp가 같지만, 후위(i++)처럼 결과와 부작용을 분리하기 위한 일관성 유지. |
| 4 | 원래 변수 i에 언제 다시 저장(부작용)하나? | 전위: i 갱신 → 결과 사용.후위: 결과 사용 → i 갱신. 명령어 순서로 강제된다. |
| 5 | 어셈블리에서 그 흐름이 어떻게 보이나? | 전위 예: add eax,1→mov [i],eax→mov [a],eax.후위 예: mov [b],eax→add eax,1→mov [i],eax. |
int a = ++i;
의사코드 흐름:
tmp = i + 1 // 증가된 값 계산
i = tmp // i에 반영 (부작용)
val = tmp // 이 값이 최종 결과로 쓰임 (a에 저장)
int b = i++;
의사코드 흐름:
val = i // 아직 증가되지 않은 값 사용 (b에 저장)
tmp = i + 1 // 증가된 값 계산
i = tmp // i에 반영 (부작용)
val은 표현식 결과용,tmp는 i 갱신용으로 역할이 다름
int demo(int i) {
int a = ++i; // 전위
int b = i++; // 후위
return a + b;
}
mov eax, [i] ; eax = i
add eax, 1 ; eax = i+1 (tmp)
mov [i], eax ; i = tmp (부작용)
mov [a], eax ; a = val (증가된 값)
mov eax, [i] ; eax = i (val)
mov [b], eax ; b = val (증가 전)
add eax, 1 ; eax = i+1 (tmp)
mov [i], eax ; i = tmp (부작용)
차이점 : 전위는
add직후 바로i·a에 쓰고, 후위는add전에 결과를 백업.
++id vs id++ → 서로 다른 AST 노드 생성i++ + i++ → 평가 순서 미정 ⇒ 정의되지 않은 동작(UB).