Search
Duplicate
🔰

[CS] Short-circuit Evaluation

간단소개
Evaluation strategy 중 하나인 short-circuit evaluation에 대해서 간단하게 알아보는 글입니다.
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
CS
Scrap
태그
short-circuit evaluation
Evaluation strategy
9 more properties
대부분의 언어에서는 빠른 처리를 위해서 Short-circuit evalution을 지원하고, 우리는 별생각 없이 조건문을 작성하곤한다. 하지만, Short-circuit evalution을 제대로 이해하고 있지 않다면 이해하지 못하는 오류에 봉착할 수 도 있다. 이번 글에서는 우리가 당연하게 사용해왔던 조건문에 적용되고 있던 Short-circuit evalution 에 대해 조금 더 깊게 고찰해보고자한다.
잘못된 내용에 대한 지적 언제나 환영입니다! @sungjpar 로 메시지 주세요!

Short-circuit evalution

Short-circuit evalution은 무엇인가?

Short-circuit evalution을 이해하기 위해서 먼저 코드를 하나 살펴보자.
int x; int a = 0; int b = 0; x = (0 && (a = b = 777)); printf("%d %d %d\n", a, b, x); x = (1 || (a = ++b)); printf("%d %d %d\n", a, b, x);
C++
복사
위 결과는 어떻게 도출될까?
Short-circuit evalution에 대해서 이해를 하고 있지 못한다면 다음과 같이 답할 것이다.
777 777 0 778 778 779
C
복사
하지만 실제 결과는 다르다.
0 0 0 0 0 1
C
복사
실제로는 위와 같은 방식으로 결과값이 나온다. 왜 그런 것일까?

Short-circuit evalution은 불필요한 연산을 건너뛴다!

프로그래머가 해당 코드를 작성할 때는 x의 값을 얻기 위해서 ab의 연산을 하는 과정이 필요하다고 생각하고 코드를 작성했을 수도 있다. 하지만, 컴파일러는 그렇게 생각하지 않는다.
0 && (a = b = 777) 해당 연산을 먼저 살펴보자. && 연산은 양 옆의 조건에 대해서 모두 True일 경우에만 True를 반환하고, 이외의 경우에는 False를 반환한다. 따라서, 이미 첫 번째 조건에서부터 False (0) 이 도출되었기 때문에 해당 조건문은 뒤에 어떤 조건이 오더라도 False가 도출이 된다. 따라서 이후에 위치한 조건은 불필요한 연산이 된다.
1 || (a = ++b) 두 번째로 해당 연산을 살펴보자. || 연산의 경우 양 옆의 조건이 모두 False일 경우에만 False를 반환하고, 이외의 경우에는 True를 반환한다. 앞선 경우와 반대로, 1 == True로 처리되기 때문에 이후의 연산에 대해서 더 이상 처리할 필요가 없다. 이
이처럼 컴파일러는 조건문에서 앞선 조건에서 이미 값이 결정된 경우에는 더 이상 이후의 코드에 대해서 평가를 진행하지 않는다. 불필요한 연산을 줄여 속도를 높이는 방법이고, 이를 잘 이해하고 있다면 좋은 코드를 작성하는데 많은 도움이 된다. 하지만, 위와 같이 잘 이해를 하고 있지 못하고 코드를 작성했다면 코드를 작성할 당시에 생각한 결과와 전혀 다른 엉뚱한 결과와 마주할 것이다.

활용

Short-circuit evalution을 활용하면 조금 더 안전하고, 깔끔한 코드 작성이 가능하다. 대표적으로, Classpointer에 대해서 NULL pointer check를 하고 이후의 조건연산을 하는 방법이다.
myCar = getCar(); if (myCar.getSpeed()) myCar.stop();
C++
복사
엉성한 코드이지만, 위 코드를 예시로 들어보겠다. Car라는 클래스인 myCar 객체는 getSpeed, stop이라는 메소드를 가지고 있다. 그런데, myCar 라는 객체가 NULL 이라면? 해당 구문은 getSpeed() 메소드를 찾지 못해 오류를 발생시킬 것이다. 이렇게 NULL이 발생하여 메소드나 멤버를 찾을 수 없는 경우가 있을때 Short-circuit evalution을 활용하여 안전한 코드를 작성할 수 있다.
myCar = getCar(); if (myCar != NULL && myCar.getSpeed()) myCar.stop();
C++
복사
이렇게 조건문을 작성한다면, myCar == NULL case에서는 False 가 확정되어 이후의 조건에 대한 평가를 진행하지 않는다. 정상적으로 객체가 할당되어 있는 경우에서는 myCar에서 getSpeed 메소드를 잘 찾아서 이후의 과정을 정상적으로 진행시킬 수 있을 것이다. (C 에서도 구조체의 활용과 같은 부분에서 Short-Circuit evalution을 잘 활용할 수 있다!)
주의!
myCar = getCar(); if (myCar.getSpeed() && myCar != NULL) myCar.stop();
C++
복사
간혹 Short-circuit evalution을 이해하지 못해 위와 같이 거꾸로 작성하시는 분들이 계신다. 이렇게 작성하면, 맥락상 전혀 의미없는 코드가 되고 말 것이다.

함께 알아두면 좋은 것

Evalutaion strategy
Lazy evaluation
함수형 프로그래밍

Short-circuit evalution을 지원하는 언어들

Search
Language
Eager operators
Short-circuit operators
Result type
제목
andor
and thenor else
Boolean
and, &, ∧ ; or, ∨
andf , orf (both user defined)
Boolean
, , (nand), (nor), etc. ∨⍲⍱
:AndIf:OrIf
Boolean1
none
&&||
Boolean
none
&&||
Boolean
none
&&, , [4]||?
int (,), opnd-dependent (&&||?)
none
&&, , [5]||?
Boolean (,), opnd-dependent (&&||?)
&|
&&, , , ||???
Boolean (,), opnd-dependent (, &&||???)
none
AND, , , OR&&||
Boolean
D3
&|
&&, , ||?
Boolean (,), opnd-dependent (&&||?)
andor
and thenor else
Boolean
andor
andalsoorelse
Boolean
.and..or.
.and..or.
Boolean
none
&&||
Boolean
&|
&&||
Boolean
&|
&&||
Last value
none
and, , , or&&||
Last value
andor
&&||
Boolean
none
andor
Last value
MUMPS (M)
&!
none
Numeric
none
ANDOR
Boolean
none
&OR
Boolean
none
&&||
Boolean
and, 5,9or
and_then, 6,9or_else
Boolean
&|
&&, , , and||or
Last value
andor
&&||
Last value
&|
&&, , , and||or
Boolean
POSIX shell (command list)
none
&&||
Last value (exit)
&|
andor
Last value
&|
&&[6]||
Boolean
&|
and:, 7or:
Boolean
Un­known
andalsoorelse
Boolean
none
and[7]or
Boolean
Beckhoff TwinCAT (IEC 61131-3)10
ANDOR
AND_THEN,[8] [9]OR_ELSE
Boolean
AndOr
AndAlsoOrElse
Boolean
AndOr
Select Case8
Numeric
And @@ {...}Or @@ {...}
And, , , Or&&||
Boolean
ZTT
&|
none
Boolean

참고문서