C #에서 해당 연산자의 단락 OR 및 단락이없는 이유는 무엇입니까?


9

주기적으로 이것에 대해 궁금합니다.

단락 OR은 항상 단락되지 않은 OR 연산자와 동일한 값을 반환합니까?

단락 OR은 항상 더 빨리 평가 될 것으로 기대합니다. 따라서 단락되지 않은 OR 연산자는 일관성을 위해 C # 언어에 포함 되었습니까?

내가 무엇을 놓쳤습니까?


9
동일한 반환 값-예 동일한 부작용-아닙니다.
Job

2
f()예외가 발생 한다고 가정 true || f()하고 and을 고려하십시오 true | f(). 차이점이 보입니까? 전자의 식은로 평가되고 true후자의 평가는 예외가 발생합니다.
scarfridge

답변:


25

두 피연산자 모두 부울 유형이없는 C에서 나오는 다양한 것을 의미했습니다. 단락 버전 || 비 단락 회로 버전 동안 부울에만 작동 | 비트 단위로 수행하는 정수 유형으로 작동합니다. 방금 단일 비트로 표시되는 부울에 대한 비 단락 논리 연산으로 작동했습니다 (0 또는 1).

http://en.wikibooks.org/wiki/C_Sharp_Programming/Operators#Logical


10
링크의 경우 +1 이 질문을 읽을 때 나는 "무엇입니까?" afaik의 공식 이름은 논리적이고 비트 단위이거나 단락 및 단락이 아니며 작동 방식의 부작용입니다.
stijn

1
+1 "부울 피연산자에서만 작동"을 볼 수 있습니다. 어쨌든 부울로 평가되는 표현식 만 사용하기 때문에 차이를 느끼지 못할 수 있습니다.
CarneyCode

2
I 확인했지만, 사실에 참 |개의 부울 값에 적용 할 때 운전자가 동일로 컴파일 or은 두 정수 값에 적용되는 경우로 CIL 연산자 - 달리 ||하는 사용 CIL로 컴파일 brtrue조건부 대해 도약.
quentin-starin

13

|(비트 단위)는와 같은 유형의 단락이 아니어야합니다 int. 거의 모든 경우 |에 정확한 결과를 계산하기 위해 표현식의 양변을 계산해야하기 때문입니다. 예를 들어 7 | f(x)? 의 결과는 무엇입니까?

경우 f(x)평가되지 않습니다, 당신은 말할 수 없다.

또한 단락 bool이 아닌 경우이 연산자를 단락시키는 것은 일관성이 없습니다 int. 그건 그렇고, 나는 |논리적으로 비교 하는 데 의도적으로 사용하지 않았 |으며 논리 연산자로 말하는 것이 매우 불편하다는 것을 알았 습니다 .

|| 그러나 단락 평가가 잘 작동하는 논리적 비교를위한 것입니다.

C와 C ++에서도 같은 연산자의 출처가 유효합니다.


5

맞습니다. 단락 OR 연산자 (||)는 항상 단락이 아닌 OR 연산자 (|)와 동일한 값을 반환합니다. (*)

그러나 첫 번째 피연산자가 true이면 단락 연산자는 두 번째 피연산자를 평가하지 않지만 비 단락 연산자는 항상 두 피연산자를 모두 평가합니다. 이는 성능에 영향을 미칠 수 있으며 때로는 부작용에 영향을 줄 수 있습니다.

따라서 성능에 관심이 있고 두 번째 피연산자의 평가로 인해 부작용이 발생하지 않으면 (또는 관심이 없다면) 단락 연산자를 사용하십시오. . 그러나 어떤 이유로 두 번째 피연산자의 부작용 이 필요한 경우 비 단락 연산자를 사용해야합니다.

비 단락 연산자를 사용해야하는 예 :

if( write_customer_to_database() != SUCCESS |
    write_supplier_to_database() != SUCCESS |
    write_order_to_database() != SUCCESS )
{
    transaction_rollback();
}

(*) 첫 번째 피연산자의 평가가 거짓으로 발생하는 두 번째 피연산자가 부작용이 아닌 참으로 평가되는 실제 왜곡 된 시나리오를 제외하고.


2
+1 그러나 성공이나 실패를 나타내는 함수를 사용하는 것 외에 (예를 들어) 부작용을 가진 함수는 일반적으로 피해야합니다 ...
Marjan Venema

1
그렇기 때문에 오늘까지 비 단락 연산자를 사용해 본 적이 없으며 아마도 그럴 가능성이 적습니다.
Mike Nakis

이 예는 엄격한 왼쪽에서 오른쪽 순서로 평가되는 피연산자에 따라 다릅니다. C #은이를 보장하지만 많은 유사한 언어 (C 및 C ++ 포함)는 그렇지 않습니다.
Keith Thompson

모든 트랜잭션이 실패하면 롤백되기 때문에 특정 예에서 단락 평가가 적합하지 않습니까? (나는 호출의 의미론에 대해 몇 가지 가정을하고있다.)
Keith Thompson

@KeithThompson 당신이 맞습니다, 비 단락 평가는 불필요한 처리를 일으킬 것입니다.이 의미에서 예제는 약간 절름발이이지만 변화를 보증하는 것은 절름발이 아닙니다. 단락 평가로 write_customer_to_database ()가 성공하면 나머지 write _... 함수는 호출되지 않으며, 실패한 경우 불필요한 조작을 수행하는 것보다 성공한 경우 올바르게 작동하는 것이 좋습니다.
Mike Nakis

4

비 단락 회로를 사용하는 데는 두 가지 이유가 있습니다.

  1. 부작용 유지 (그러나 임시 변수로 코드를 작성하는 것이 더 명확합니다)

  2. 방해 타이밍 공격 단락의 포크를 피함으로써 (제 피연산자는 변수가 있지만 컴파일러든지 할 수있는 마이크로 최적화 있다면 이것도 런타임 효율을 향상시킬 수 있음)


이것이 유일하게 제공된 이유이며, 이것이 왜 가장 높은 표를 얻은 답변이 아닌지 모르겠습니다 ...
Behrooz

2

연산자의 오른쪽 절에 부작용이 있고 프로그래머가 반환 값을 확인하기 전에 부작용이 발생하기를 원한 경우.


5
Eek. 이런 식으로 코드를 작성하지 마십시오. 부작용에 의존하는 경우 두 가지 다른 표현이 있고 결과를 할당 한 후 나중에 테스트하십시오 .
Konrad Rudolph
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.