전위 또는 후위연산자와 비교 연산자가 동시에 존재할때 해석방법이 어떻게 되나요?
글쓴이: jhkim123 / 작성시간: 일, 2019/10/13 - 9:35오후
안녕하십니까 저는 전산직 공부하고 있는 공시생입니다
학교때 쓰던 책도 살펴보고 비주얼 스튜디오도 돌려서 디버깅을 해봤는데
확신이 안되어 쪼개서 설명 해주셨으면 해서 여기에 질문 올립니다
#include <stdio.h> int main() { int i = 3; int j = 4; if((++i > j--) && (i++ < --j)) i = i-- + ++j; else j = i-- - --j; printf("%d₩’. i); }
시험문제는 띄어쓰기나 중괄호를 안쓰는 형태로 나오네요
비교 당시에 if((3 > 4) && (3 < 4)) i = i-- + ++j; 이렇게 비교한후 증감이 이루어지나요?
*여기에 글 처음쓰니 양식 같은게 틀린거 있으면 말해주시면 글 수정하겠습니다
Forums:
...
문제가 잘못됐네요.
i = i-- + ++j
같은 코드는 잘못된 코드입니다. ++/-- 연산자가 쓰인 변수를 같은 statement 안에서 또 업데이트하려고 하면 안됩니다. (정확히 말하면 좀 더 복잡한데 저도 자세한 규칙은 잘 모르니 대충 쓰겠습니다. -_-)if 문 안의 조건은 문제가 없습니다. &&는 무조건 앞부분을 먼저 계산하고 그 결과가 참일 때만 뒷부분을 계산하는 성질이 있기 때문에 결국 이렇게 됩니다:
(1) 첫번째 조건: ++i > j--
여기서 ++i의 값은 4, j--의 값은 역시 4입니다. 물론 이 식을 수행한 다음 i, j의 값은 각각 4, 3이 됩니다. 보시다시피 ++i > j--는 거짓이기 때문에 두번째 조건은 수행되지 않습니다.
(2) 여기서 else 문으로 넘어가는데, --j를 수행하면서 j의 값을 동시에 변경하려 하고 있습니다. 잘못된 코드입니다.
1. C99의 기준에서, 인접한 두 sequence
1. C99의 기준에서, 인접한 두 sequence point 사이에서 object는 최대 단 한 번만 변경될 수 있습니다.
1)
(++i > j--) && (i++ < --j)
의 경우, && 연산자는 왼쪽 operand를 계산한 후 sequence point를 찍기 때문에 문제 없습니다.2)
i = i-- + ++j
와j = i-- - --j
는 각각 i와 j를 인접한 sequence point 안에서 두 번 변경하고 있기 때문에 undefined behavior입니다.3) 현실적으로 보면, if statement의 조건은 명백히 거짓이고, 따라서 else 부분이 실행되는데 여기서 문제가 되는 부분은 j의 변경이니까, i는 그냥 무난히 3이 될 거라고 생각할 수도 있습니다. 제가 gcc로 컴파일해서 돌려 봐도 그렇게 나오는군요.
이건 아무리 undefined behavior라고 해도 컴파일러가 딱히 더 비이성적으로 동작할 필요는 없을 거라는 믿음 하에서 그렇게 생각하는 것입니다. 하지만 undefined behavior를 유발하는 프로그램은 이론상 어떤 일이든 할 수 있고, 결과적으로 i가 어떤 값을 가지든 뭐라 불평할 수가 없지요.
2. C11에서 이 규칙은 약간 바뀌었는데, 간단히 요약하면 인접한 sequence point 사이에서 어떤 scalar object에 대해 side effect가 두 번 이상 일어났다고 하더라도 그 사이에 순서가 잘 정의되면 허용되는 규칙이 생겼습니다.
이 규칙을 따지려면 expression을 이루는 구성요소 하나하나에서 sequenced before/after를 따져봐야 해서 상당히 짜증스러운데, 대충 살펴보니
j = i-- - --j
에서 j에 대해 발생하는 두 side effects 사이엔 정해진 순서가 없는 것 같네요. 그러면 여전히 undefined behavior입니다.댓글 달기