단락 논리 연산자가 필수입니까?평가 순서는요?
ANSI 규격은 논리 연산자를 C 또는 C++ 중 하나로 단락하도록 의무화하고 있습니까?
K&R 서적을 보니 헷갈리네요.고객님의 코드가 단락된 작업에 의존해서는 안 된다고 되어 있습니다.그럴지도 모르기 때문입니다.표준에서 논리 운영은 항상 단락이라고 되어 있는 부분을 누군가 지적해 주실 수 있습니까?저는 주로 C++에 관심이 있는데, C에 대한 답변도 좋을 것 같습니다.
평가 순서가 엄밀하게 정의되어 있지 않기 때문에, 식내의 함수는 특정의 순서로 실행되거나 상정되어서는 안 됩니다.문장이 끝날 때까지 모든 참조 함수는 호출되지만 컴파일러는 가장 효율적인 순서를 선택할 수 있습니다.
이 표현식의 평가순서는 규격에 나와 있습니까?
if( functionA() && functionB() && functionC() ) cout<<"Hello world";
예, 작업자의 경우 단락 및 평가 순서가 필요합니다.||
그리고.&&
C와 C++ 규격 양쪽에서 사용할 수 있습니다.
C++ 표준에는 다음과 같이 기술되어 있습니다(C 표준에는 동등한 조항이 있어야 합니다).
1.9.18
다음 표현에 대한 평가에서
a && b a || b a ? b : c a , b
이들 식에서 연산자의 삽입된 의미를 사용하여 첫 번째 식(12)의 평가 후에 시퀀스 포인트가 있습니다.
C++에는 추가 트랩이 있습니다.단락은 연산자를 과부하로 하는 타입에는 적용되지 않습니다.||
그리고.&&
.
각주 12:이 단락에서 나타내는 연산자는 조항 5에서 설명한 바와 같이 내장 연산자이다.이들 연산자 중 하나가 유효한 컨텍스트에서 과부하되면(조항 13), 사용자 정의 연산자 함수를 지정하면 표현식은 함수 호출을 지정하고 연산자는 이들 사이에 암묵적인 시퀀스 포인트를 가지지 않고 인수 리스트를 형성한다.
특별한 요건이 없는 한 보통 이러한 연산자를 C++로 오버로드하지 않는 것이 좋습니다.할 수 있지만, 특히 이러한 연산자가 오버로드된 유형의 템플릿을 인스턴스화하여 간접적으로 사용되는 경우, 다른 사람의 코드에서 예상되는 동작을 방해할 수 있습니다.
단락 평가 및 평가 순서는 C와 C++ 모두에서 필수 의미 표준입니다.
그렇지 않다면, 이런 코드는 일반적인 관용어가 아닐 것입니다.
char* pChar = 0;
// some actions which may or may not set pChar to something
if ((pChar != 0) && (*pChar != '\0')) {
// do something useful
}
섹션 6.5.13 C99 사양의 논리 AND 연산자(PDF 링크)는 다음과 같이 말한다.
(4) 비트 바이너리 & 연산자와 달리 & 연산자는 왼쪽에서 오른쪽으로의 평가를 보증합니다.첫 번째 피연산자의 평가 후에 시퀀스 포인트가 있습니다.첫 번째 피연산자가 0과 같은 경우 두 번째 피연산자는 평가되지 않습니다.
마찬가지로 섹션 6.5.14 논리 OR 연산자는 다음과 같이 말한다.
(4) bitwise | 연산자와 달리 | 연산자는 왼쪽에서 오른쪽으로의 평가를 보증합니다.첫 번째 피연산자의 평가 후에 시퀀스 포인트가 있습니다.첫 번째 피연산자가 0과 동일하지 않은 경우 두 번째 피연산자는 평가되지 않습니다.
C++ 표준에서도 유사한 표현을 찾을 수 있습니다. 이 초안의 섹션 5.14를 확인하십시오.체커들이 다른 응답에서 알 수 있듯이 & 또는 |를 덮어쓰면 두 오퍼랜드가 모두 일반 함수 호출이 되기 때문에 평가되어야 합니다.
네, (평가 순서와 단락 모두)를 의무화하고 있습니다.이 예에서는 모든 함수가 true를 반환하는 경우 호출 순서는 function A에서 function B로 function C로 엄밀하게 지정됩니다.다음과 같은 용도로 사용됩니다.
if(ptr && ptr->value) {
...
}
쉼표 연산자:
// calls a, then b and evaluates to the value returned by b
// which is used to initialize c
int c = (a(), b());
왼쪽과 오른쪽 피연산자 사이를 말합니다.&&
,||
,,
첫 번째와 두 번째/세 번째 피연산자 사이?:
(조건 연산자)는 "시퀀스 포인트"입니다.모든 부작용은 그 시점 이전에 완전히 평가된다.이것은 안전합니다.
int a = 0;
int b = (a++, a); // b initialized with 1, and a is 1
콤마 연산자는 구분하기 위해 사용되는 구문 콤마와 혼동해서는 안 됩니다.
// order of calls to a and b is unspecified!
function(a(), b());
C++ 규격에 따르면5.14/1
:
& & 연산자는 왼쪽에서 오른쪽으로 그룹화됩니다.오퍼랜드 모두 암묵적으로 타입 부울(clause 4)로 변환됩니다.결과는 두 오퍼랜드가 모두 true이면 true이고 그렇지 않으면 false입니다.&과 달리 &는 왼쪽에서 오른쪽으로의 평가를 보증합니다.첫 번째 피연산자가 false일 경우 두 번째 피연산자는 평가되지 않습니다.
그리고...5.15/1
:
|| 연산자는 왼쪽에서 오른쪽으로 그룹화합니다.오퍼랜드 모두 암묵적으로 bool로 변환됩니다(clause 4).오퍼랜드 중 하나가 true이면 true를 반환하고 그렇지 않으면 false를 반환합니다.| 와 달리 | | 에서는 왼쪽에서 오른쪽으로의 평가가 보증됩니다.게다가 첫 번째 피연산자가 true로 평가될 경우 두 번째 피연산자는 평가되지 않습니다.
양쪽 옆에 다음과 같이 표시되어 있습니다.
결과는 bool입니다.일시적 파괴(12.2)를 제외한 첫 번째 식의 모든 부작용은 두 번째 식이 평가되기 전에 발생한다.
그 외에도1.9/18
말한다
각 표현에 대한 평가에서
a && b
a || b
a ? b : C
a , b
이러한 표현식(5.14, 5.15, 5.16, 5.18)에서 연산자의 삽입 의미를 사용하여 첫 번째 표현식의 평가 후에 시퀀스 포인트가 있습니다.
Wikipedia를 신뢰하는 경우:
[
&&
그리고.||
]는 비트 연산자 & 및 |와는 의미적으로 구별됩니다.이는 결과가 왼쪽에서만 결정될 경우 올바른 피연산자를 평가하지 않기 때문입니다.
아주 아주 조심해요.
기본 유형의 경우 이들은 바로 가기 연산자입니다.
그러나 사용자 자신의 클래스 또는 열거 유형에 대해 이러한 연산자를 정의하면 바로 가기가 아닙니다.이러한 다른 상황에서는 이러한 사용법이 의미적으로 다르기 때문에 이러한 연산자를 정의하지 않는 것이 좋습니다.
를 위해operator &&
그리고.operator ||
기본 유형의 경우 평가 순서는 왼쪽에서 오른쪽으로 표시됩니다(그렇지 않으면 쇼트 커팅이 어려울 수 있습니다). 그러나 사용자가 정의하는 과부하 연산자의 경우 기본적으로 방법을 정의하는 구문 설탕이므로 매개변수의 평가 순서가 정의되지 않습니다.
이전 K&R에서 직접:
C는 다음을 보증합니다.
&&
그리고.||
왼쪽에서 오른쪽으로 평가됩니다.이것이 중요한 케이스는 곧 알게 될 것입니다.
질문의 요점은 C++ 연산자의 우선 순위와 관련성에 있습니다.기본적으로 여러 연산자가 있고 괄호가 없는 식에서 컴파일러는 이러한 규칙을 따라 식 트리를 구성합니다.
우선은, 당신이 어떤 것을 가지고 있을 때A op1 B op2 C
, 다음과 같이 그룹화할 수 있습니다.(A op1 B) op2 C
또는A op1 (B op2 C)
.한다면op1
보다 우선도가 높다op2
첫 번째 표현이 나옵니다.안 그러면 두 번째 걸 받을 거예요.
연관성을 위해서, 여러분이 어떤 것을 가지고 있을 때A op B op C
, 다시 그룹화할 수 있습니다.(A op B) op C
또는A op (B op C)
.한다면op
연관성을 떠나 첫 번째 표현으로 끝납니다.적절한 연관성이 있다면 두 번째 연관성이 있습니다.이는 동일한 우선순위 수준의 연산자에게도 적용됩니다.
이 특별한 경우,&&
보다 우선도가 높다||
이 표현은 다음과 같이 평가됩니다.(a != "" && it == seqMap.end()) || isEven
.
순서 자체는 expression-tree 형식에서 "왼쪽에서 오른쪽으로"입니다.그래서 먼저 평가하겠습니다.a != "" && it == seqMap.end()
모든 표현이 참일 경우, 그렇지 않을 경우 로 이동합니다.isEven
이 순서는 당연히 왼쪽-서브식 안에서 반복됩니다.
흥미로운 이야기지만 우선순위의 개념은 수학 표기법에 뿌리를 두고 있습니다.같은 일이 에서 일어나다a*b + c
,어디에*
보다 우선도가 높다+
.
더욱 흥미로운/관찰적인 표현은 비파손적 표현입니다.A1 op1 A2 op2 ... opn-1 An
여기서 모든 연산자가 동일한 우선순위를 가지며, 우리가 형성할 수 있는 바이너리 식 트리의 수는 이른바 카탈로니아 숫자로 지정됩니다.큼직함n
은 굉장히 d, ᄃ.
언급URL : https://stackoverflow.com/questions/628526/is-short-circuiting-logical-operators-mandated-and-evaluation-order
'programing' 카테고리의 다른 글
bootstrap-vue 테이블의 헤더 행을 숨기는 방법 (0) | 2022.09.01 |
---|---|
Vuex 모듈의 TypeScript 오류 - 하위 모듈이 Vuex의 인덱스 모듈에 할당할 수 없는 잘못된 오류 (0) | 2022.09.01 |
이중 값을 나타내는 데 필요한 최대 문자 길이는 얼마입니까? (0) | 2022.09.01 |
Vue/vuetify, 라우터 링크를 탭에 추가하는 방법 (0) | 2022.09.01 |
Android에서 PreferenceActivity에서 SharedPreferences를 가져오려면 어떻게 해야 합니까? (0) | 2022.09.01 |