[c] 이 버전의 논리 AND C에서 단락 동작이 표시되지 않는 이유는 무엇입니까?

예, 이것은 숙제 질문이지만 주제에 대해 조사하고 상당한 양의 깊이 생각을했지만 이것을 이해할 수 없습니다. 질문은이 코드 조각이 단락 동작을 나타내지 않으며 그 이유를 묻습니다. 그러나 그것은 단락 동작을 보이는 것처럼 보이므로 누군가가 왜 그렇지 않은지 설명 할 수 있습니까?

C에서 :

이 경우에 저에게 보이는 a거짓, 프로그램 평가하려고하지 않습니다 b전혀하지만, 내가 잘못해야합니다. b이 경우 프로그램이 터치하지 않아도되는 이유는 무엇 입니까?



답변

이것은 속임수 질문입니다. 메서드에 b대한 입력 인수 sc_and이므로 항상 평가됩니다. 다른 단어에서는 sc_and(a(), b())호출 a()하고 호출 한 다음 b()(순서는 보장되지 않음) sc_and결과 를 호출 a(), b()하여 a?b:0. 절대적으로 단락되는 삼항 연산자 자체와는 관련이 없습니다.

최신 정보

내가 이것을 ‘속임수 질문’이라고 부르는 이유와 관련하여 : ‘단락’을 고려할 위치에 대한 잘 정의 된 컨텍스트가 부족하기 때문입니다 (적어도 OP에 의해 재현 됨). 함수 정의 만 주어 졌을 때 많은 사람들 은 질문의 맥락 이 함수 의 본문 에 대해 묻는다고 가정 합니다 . 그들은 종종 그 기능을 그 자체로 표현으로 간주하지 않습니다. 이것이 질문의 ‘속임수’입니다. 일반적으로 프로그래밍에서, 특히 규칙에 대한 많은 예외가있는 C와 같은 언어에서는 그렇게 할 수 없다는 것을 상기시키기 위해. 예를 들어 질문이 다음과 같이 요청 된 경우 :

다음 코드를 고려하십시오. main 에서 호출 될 때 sc_and exibit 단락 동작을 수행합니다 .

sc_and자신의 도메인 특정 언어 에서 그 자체로 운영자로 생각 하고 호출 sc_and이 일반처럼 단락 동작 을 나타내는 지&& 평가 해야한다는 것이 즉시 분명 해질 것 입니다. 삼항 연산자에 초점을 맞추지 않고 대신 C / C ++의 함수 호출 메커니즘에 초점을 맞춰야한다는 것이 분명하기 때문에 트릭 질문이라고 생각하지 않습니다. sc_and단락 을 수행하는 후속 질문에 멋지게 작성하십시오 #define. 이는 함수 가 아닌 사용을 포함 합니다).

삼항 연산자 자체가 단락 (또는 ‘조건부 평가’와 같은 다른 것)을 수행하는 것을 호출할지 여부는 단락에 대한 정의에 따라 다르며 이에 대한 다양한 의견을 읽을 수 있습니다. 내 생각에는 그렇지만 실제 질문이나 내가 ‘트릭’이라고 부르는 이유와는별로 관련이 없습니다.


답변

성명서

실행하는, b++피연산자 경우 평가되지 a로 평가 false(단락 동작). 이는 부작용이 발생 b하지 않음을 의미합니다 .

이제 함수를 살펴보십시오.

그리고 이것을 불러

이 경우, 여부 a입니다 true또는 false, b++항상 평가됩니다 1 에 함수 호출 및 부작용 중 b항상 일어날 것이다.

같은 사실입니다


1 함수 인수의 평가 순서가 지정되지 않았습니다.


답변

이미 다른 사람들이 지적했듯이, 두 인수로 함수에 전달되는 것이 무엇이든 전달되는대로 평가됩니다. 이것이 테너 리 연산 이전의 방식입니다.

반면에 이것은

이로, “단락” 매크로 함수 호출이와 함수의 인수없이 평가 (들) 수행을 의미하지는 않습니다.


답변

@cmasters 주석에 명시된 오류를 수정하도록 편집되었습니다.


returned 표현식은 단락 평가를 나타내지 만 함수 호출은 그렇지 않습니다.

전화 해보세요

함수 호출 1 / 0은 사용되지 않지만 평가 하므로 0으로 나누기 오류가 발생할 수 있습니다.

ANSI C 표준 (초안)에서 발췌 한 관련 내용은 다음과 같습니다.

2.1.2.3 프로그램 실행

추상 기계에서 모든 표현식은 의미 체계에 지정된대로 평가됩니다. 실제 구현은 해당 값이 사용되지 않고 필요한 부작용이 발생하지 않는다고 추론 할 수있는 경우 표현식의 일부를 평가할 필요가 없습니다.

3.3.2.2 함수 호출

….

의미론

함수 호출을 준비 할 때 인수가 평가되고 각 매개 변수에 해당 인수의 값이 할당됩니다.

내 생각 엔 각 인수는 전체 인수 목록이라고 표현으로 평가되지만 있다는 것입니다 하지 따라서 비 SCE 동작은 필수입니다, 식.

C 표준의 심해 표면에 대한 스 플래셔로서 저는 두 가지 측면에 대한 적절한 정보에 감사드립니다.

  • 평가 1 / 0가 정의되지 않은 동작을 생성 합니까 ?
  • 인수 목록이 표현식입니까? (나는 그렇게 생각하지 않는다)

추신

C ++로 이동 sc_and하고 inline함수 로 정의하더라도 SCE를 얻지 못합니다 . @alk 처럼 C 매크로로 정의 하면 확실히 그렇게 될 것입니다.


답변

삼항 연산 단락을 명확하게 보려면 정수 대신 함수 포인터를 사용하도록 코드를 약간 변경해보십시오.

그런 다음 컴파일하십시오 (거의 최적화 없이도 : -O0!). 당신은 볼 b()경우 실행되지 않습니다 a()반환 거짓.

생성 된 어셈블리는 다음과 같습니다.

따라서 다른 사람들이 올바르게 지적했듯이 질문 트릭은 단락하지 않는 호출 (값별 호출)에 대한 매개 변수 평가 대신 단락 ( ‘조건부 평가’라고 함)을 수행하는 삼항 연산자 동작에 초점을 맞추도록하는 것입니다.


답변

C 삼항 연산자는 값이 반환 될 수있는 경우 표현식 bc가 제공하는 값을 결정하기 위해 단일 표현식 a (조건) 만 평가하므로 단락 할 수 없습니다 .

다음 코드 :

다음 코드와 거의 동일합니다.

표현식 a 는 && 또는 ||와 같은 다른 연산자로 구성 될 수 있습니다. 값을 반환하기 전에 두 개의 표현식을 평가할 수 있기 때문에 단락 될 수 있지만 단락을 수행하는 삼항 연산자로 간주되지 않고 일반 if 문에서와 같이 조건에서 사용되는 연산자로 간주됩니다.

최신 정보:

삼항 연산자가 단락 연산자라는 논쟁이 있습니다. 인수는 모든 피연산자를 평가하지 않는 모든 연산자가 아래 주석의 @aruisdante에 따라 단락을 수행한다고 말합니다. 이 정의가 주어지면 삼항 연산자가 단락되고 이것이 원래 정의 인 경우 동의합니다. 문제는 “단락 (short-circuit)”이라는 용어가 원래 이러한 동작을 허용하는 특정 종류의 연산자에 사용되었으며 논리 / 부울 연산자이며 그 이유 만 설명하려고한다는 것입니다.

문서 다음 단락 평가 , 단락 평가는 첫 번째 피연산자가 첫 번째 피연산자 인 && 연산자, 이것이 두 번째 무관 할 것으로 알고있는 방식으로 언어로 구현 부울 연산자 칭한다 거짓 , 그리고 || 연산자는 첫 번째 피연산자 true 이며 C11 사양 은 6.5.13 논리 AND 연산자 및 6.5.14 논리 OR 연산자에서도이를 기록합니다.

즉, 단락 동작을 식별하려면 첫 번째 피연산자가 두 번째 피연산자와 관련이없는 경우 부울 연산자처럼 모든 피연산자를 평가해야하는 연산자에서이를 식별해야합니다. 이는 단락이 논리 연산자에서 발생하기 때문에 MathWorks 의 “논리적 단락”섹션에서 단락에 대한 다른 정의에 기록 된 내용과 일치 합니다.

내가 삼항 연산자라고도하는 C 삼항 연산자를 설명하려고했지만 피연산자 중 두 개만 평가하고 첫 번째 피연산자를 평가 한 다음 두 번째 피연산자를 평가합니다. 첫 번째. 항상 이렇게합니다. 어떤 상황에서도이 세 가지를 모두 평가해서는 안되므로 어떤 경우에도 “단락”이 없습니다.

항상 그렇듯이, 무언가가 옳지 않다는 것을 알게된다면, 단지 반대표가 아니라 이에 반대하는 의견을 적어주세요. 이것은 단지 SO 경험을 더 악화시킬뿐입니다. 그리고 저는 우리가 단지 대답 만하는 훨씬 더 나은 커뮤니티가 될 수 있다고 믿습니다. 하나는 동의하지 않습니다.


답변