문제의 역사:
논리 연산자 &&와 ||는 복잡한 논리 조건을 검사하기 위해 C언어에 도입되었습니다. 이들의 작동 방식의 특징은 첫 번째 피연산자에 의해 결과를 명확히 결정할 수 있는 경우 두 번째 피연산자가 계산되지 않는 짧은 회로 평가(short-circuit evaluation)를 지원한다는 것입니다.
문제:
많은 프로그래머는 두 피연산자가 항상 계산될 것이라고 기대하거나, 두 번째 피연산자에서 부작용을 잘못 사용하여 반드시 실행될 것이라고 가정합니다. 실제로 이는 오류, 자원 누수 및 예기치 않은 동작으로 이어질 수 있습니다.
해결책:
짧은 회로 평가 메커니즘을 이해하면, 특히 포인터, 자원 및 파일 검사에서 안전한 구조를 만드는 데 도움이 됩니다. 표현식의 오른쪽 부분에서 부작용을 사용하는 것은 의식적으로만 허용됩니다. 안전한 검사의 예:
if (ptr && ptr->field) { /* ... */ }
주요 특징:
if (0 && f()) 구문에서 f()는 실행될까요?
아니요, f() 함수는 호출되지 않습니다, 왜냐하면 결과가 이미 명확하기 때문입니다 — 표현식이 거짓이므로 추가 계산은 무의미합니다.
다음 구문은? if (1 || f())?
다시 f()는 호출되지 않습니다: 첫 번째 피연산자 이후에 결과가 이미 참이기 때문입니다.
부작용이 있는 함수 실행 순서를 제어하기 위해 && 및 || 연산자를 사용할 수 있나요?
기술적으로는 가능하지만, 이러한 제어는 읽기 어려운 불안정한 코드를 초래합니다. 부작용을 위해 단순히 짧은 회로 동작에 의존하지 말고 함수 호출 순서를 명확하게 작성하는 것이 좋습니다.
if (flag || process()) { // ... }
flag가 참이면 process는 절대 호출되지 않습니다.
장점:
단점:
if (!flag) process();
장점:
단점: