"as-if"규칙은 정확히 무엇입니까?


89

제목에서 알 수 있듯이

"as-if"규칙은 정확히 무엇입니까?

일반적인 대답은 다음과 같습니다.

프로그램의 관찰 가능한 동작을 변경하지 않는 모든 코드 변환을 허용하는 규칙

때때로 우리는이 규칙에 기인하는 특정 구현에서 동작을 계속 얻습니다. 여러 번 잘못되었습니다. 이 규칙은 정확히 무엇입니까? 표준은이 규칙을 섹션이나 단락으로 명확하게 언급하지 않습니다. 그렇다면 정확히이 규칙의 범위에 속하는 것은 무엇입니까? 나에게 그것은 표준에 의해 자세히 정의되지 않은 회색 영역처럼 보입니다. 누군가가 표준에서 참조를 인용하는 세부 사항에 대해 자세히 설명 할 수 있습니까?

참고 : 두 언어와 관련이 있으므로 C 및 C ++ 둘 다로 태그를 지정하십시오.


2
추상 기계를 의미합니다.
Alexey Frunze 2013 년

" 두 언어 모두와 관련이 있기 때문에 C와 C ++ 둘 다로 태그를 지정합니다. "모든 언어와 관련이 있습니다.
curiousguy

@AlexeyFrunze " 그것은 추상적 인 기계를 의미한다. 이것은"추상 기계 "가 끝이 아닌 도구이고, 실제가 아닌 사양 도구 인"추상적 "이기 때문에 적합성 측면에서 무관 한 상태를 의미한다.
curiousguy

답변:


98

" as-if "규칙은 무엇입니까?

" as-if "규칙은 기본적으로 합법적 인 C ++ 프로그램에서 구현이 수행 할 수있는 변환을 정의합니다. 요컨대, 프로그램의 " 관찰 가능한 동작 "에 영향을주지 않는 모든 변환 이 허용됩니다 (정확한 정의는 아래 참조).

목표는 프로그램의 동작이 추상 기계 측면에서 C ++ 표준에 지정된 의미를 준수하는 한 구현에 최적화를 수행 할 수있는 자유를 제공하는 것입니다.


표준은이 규칙을 어디에 도입합니까?

C ++ 11 표준은 1.9 / 1 항에 " as-if "규칙을 도입합니다 .

이 국제 표준의 의미 설명은 매개 변수화 된 비 결정적 추상 기계를 정의합니다. 이 국제 표준은 준수 구현의 구조에 대한 요구 사항을 지정하지 않습니다. 특히 추상 기계의 구조를 복사하거나 에뮬레이트 할 필요가 없습니다. 오히려, 아래에 설명 된대로 추상 기계 의 관찰 가능한 동작 을 에뮬레이트하기 위해서는 준수 구현이 필요 합니다.

또한 설명 각주는 다음을 추가합니다.

이 조항은 관찰 가능한 행동으로부터 결정될 수있는 한, 결과가 마치 요구 사항을 준수한 것처럼 결과가이 국제 표준의 요구 사항을 무시할 수 있기 때문에 "as-if"규칙이라고도합니다. 프로그램의. 예를 들어, 실제 구현은 해당 값이 사용되지 않고 프로그램의 관찰 가능한 동작에 영향을 미치는 부작용이 발생하지 않는다고 추론 할 수있는 경우 표현식의 일부를 평가할 필요가 없습니다.


규칙은 정확히 무엇을 요구합니까?

1.9 / 5 항은 다음을 추가로 명시합니다.

잘 구성된 프로그램을 실행하는 준수 구현 은 동일한 프로그램 및 동일한 입력을 사용하여 추상 기계의 해당 인스턴스의 가능한 실행 중 하나와 동일한 관찰 가능한 동작을 생성해야합니다 . 그러나 그러한 실행에 정의되지 않은 작업이 포함되어있는 경우이 국제 표준은 해당 입력으로 해당 프로그램을 실행하는 구현에 대한 요구 사항을 지정하지 않습니다 (첫 번째 정의되지 않은 작업 이전의 작업에 대해서도).

이 제약은 "잘 구성된 프로그램을 실행" 할 때만 적용되며 정의되지 않은 동작을 포함하는 프로그램을 실행할 때 가능한 결과는 제약이 없다는 점을 강조 할 가치가 있습니다. 이것은 1.9 / 4 절에도 명시되어 있습니다.

다른 특정 연산은이 국제 표준에서 정의되지 않은 것으로 설명됩니다 (예 : const 객체 수정 시도의 효과). [참고 : 이 국제 표준은 정의되지 않은 동작을 포함하는 프로그램의 동작에 대한 요구 사항을 부과하지 않습니다 . —end note]

마지막으로, " 관찰 가능한 행동 " 의 정의와 관련하여 1.9 / 8 항은 다음과 같습니다.

준수 구현에 대한 최소 요구 사항은 다음과 같습니다.

— 휘발성 객체에 대한 액세스는 추상 기계의 규칙에 따라 엄격하게 평가됩니다.

— 프로그램 종료시, 파일에 기록 된 모든 데이터는 추상 의미론에 따라 프로그램을 실행했을 때 발생할 수있는 결과 중 하나와 동일해야합니다.

— 대화 형 장치의 입력 및 출력 역학은 프로그램이 입력을 기다리기 전에 프롬 프팅 출력이 실제로 전달되는 방식으로 발생해야합니다. 대화 형 장치를 구성하는 것은 구현에 따라 정의됩니다.

이를 총체적으로 프로그램의 관찰 가능한 동작이라고합니다 . [ 참고 : 추상과 실제 의미 간의보다 엄격한 대응은 각 구현에 의해 정의 될 수 있습니다. — 끝 참고 ]


이 규칙이 적용되지 않는 상황이 있습니까?

내가 아는 한, " as-if "규칙에 대한 유일한 예외 는 복사 / 이동 제거이며, 이는 클래스의 복사 생성자, 이동 생성자 또는 소멸자가 부작용이 있더라도 허용됩니다. 이에 대한 정확한 조건은 12.8 / 31 절에 명시되어 있습니다.

특정 기준이 충족되면 복사 / 이동 작업을 위해 선택한 생성자 및 / 또는 객체에 대한 소멸자가 부작용이 있더라도 구현시 클래스 객체의 복사 / 이동 구성을 생략 할 수 있습니다 . [...]


2
이 인용문을 본 적이 있습니다. 명확하지 않은 것은 관찰 가능한 행동의 정의입니다. 관찰 가능한 행동이란 정확히 무엇입니까? as-if 규칙에 대한 예외 인 복사 제거는 거의 잘 알려져 있으며 실제로 내 질문의 일부가 아닙니다.
Alok 저장

2
@AlokSave : C 표준에서는 "휘발성 개체에 액세스, 개체 수정, 파일 수정 또는 이러한 작업을 수행하는 함수 호출이 모두 부작용입니다"를 볼 수 있습니다. 아마도 C ++ 표준에 동등한 것이있을 것입니다. 비공식적으로 "외부 세계와의 상호 작용을 바꾸는 모든 것"이라고 생각합니다.
Oliver Charlesworth 2013 년

1
추상 기계의 상태를 변경하는 모든 동작 (즉, 전달 된 변수 또는 전역 변수를 변경하거나 I / O 장치에 읽고 쓰는 것).
Mats Petersson 2013 년

1
이것은 나중에 관찰 할 수있는 일이 일어나지 않는 한 아무것도하지 않는 무한 루프를 삭제할 수 있다는 것을 의미합니까?
해롤드

5
특히 주목해야 할 점은 법률 프로그램 에만 적용된다는 것 입니다. 정의되지 않은 동작을 호출하는 모든 것은 명시 적으로 모든 범위를 벗어납니다.
vonbrand 2013 년

15

C11에서는 규칙이 해당 이름으로 호출되지 않습니다. 그러나 C는 C ++와 마찬가지로 추상 기계 측면에서 동작을 정의합니다. as-if 규칙은 C11 5.1.2.3p4 및 p6에 있습니다 .

  1. 추상 기계에서 모든 표현식은 의미 체계에 지정된대로 평가됩니다. 실제 구현은 해당 값이 사용되지 않고 필요한 부작용이 발생하지 않는다고 추론 할 수있는 경우 표현식의 일부를 평가할 필요가 없습니다 (함수를 호출하거나 휘발성 개체에 액세스하여 발생하는 결과 포함).

  2. [...]

  3. 준수 구현에 대한 최소 요구 사항은 다음과 같습니다.

    • volatile객체에 대한 액세스 는 추상 기계의 규칙에 따라 엄격하게 평가됩니다.
    • 프로그램 종료시 파일에 기록 된 모든 데이터는 추상 의미론에 따라 프로그램을 실행했을 때 생성 된 결과와 동일해야합니다.
    • 대화 형 장치의 입력 및 출력 역학은 7.21.3에 지정된대로 발생해야합니다 . 이러한 요구 사항의 목적은 프로그램이 입력을 대기하기 전에 프롬 프팅 메시지가 실제로 나타나도록하기 위해 버퍼링되지 않은 또는 라인 버퍼링 된 출력이 가능한 한 빨리 나타나도록하는 것입니다.

     

    이것은 프로그램의 관찰 가능한 동작입니다.


-1

C, C ++, Ada, Java, SML ... 프로그램의 (일반적으로 많은 가능한 비 결정적) 동작을 설명하여 잘 지정된 프로그래밍 언어 (I / O 포트의 일련의 상호 작용에 노출됨) , 뚜렷한 as-if 규칙이 없습니다 .

구별 규칙 의 예로는 0으로 나누면 예외가 발생하거나 (Ada, Caml) null 역 참조가 예외 (Java)가 발생한다는 규칙이 있습니다. 다른 것을 지정하기 위해 규칙을 변경할 수 있으며 다른 언어로 끝날 것입니다 (어떤 사람들은 "방언"(*)이라고 부르기도합니다.) 구별되는 것과 같은 프로그래밍 언어의 뚜렷한 용도를 지정하는 별개의 규칙이 있습니다 . 문법 규칙은 일부 구문 구조를 다룹니다 .

(*) 일부 언어 학자에 따르면 방언은 "군대"가있는 언어입니다. 그런 맥락에서 이는위원회와 특정 산업의 컴파일러 편집자가없는 프로그래밍 언어를 의미 할 수 있습니다.

as-if 규칙은 별개의 규칙이 아닙니다 . 특히 어떤 프로그램도 다루지 않으며 어떤 식 으로든 논의, 제거 또는 변경 될 수있는 규칙조차도 아닙니다 . 소위 "규칙"은 프로그램 의미가 정의되어 있음을 반복하며 이식 가능 (보편적) 만 가능합니다. 프로그램 실행과 "외부"세계의 가시적 인 상호 작용이라는 용어로 정의됩니다.

외부 세계는 I / O 인터페이스 (stdio), GUI, 심지어 순수한 응용 언어의 결과 값을 출력하는 대화 형 인터프리터 일 수 있습니다. C와 C ++에는 휘발성 객체에 대한 (모호하게 지정된) 액세스가 포함되어 있습니다. 이는 특정 지점의 일부 객체가 ABI를 명시 적으로 언급하지 않고 ABI (Application Binary Interface)에 따라 엄격하게 메모리에 표현되어야한다는 또 다른 방법입니다.

A는 무엇의 정의 실행 추적 , 또한 "있는 그대로의 경우 규칙"무엇을 의미하는지 가시 또는 관찰 행동을 정의라고합니다. as-if 규칙은 그것을 설명 하려고 시도 하지만 그렇게함으로써 구현에 더 많은 여유를주는 추가적인 의미 규칙이라는 표현을 제공하기 때문에 사물을 명확히하기보다는 사람들을 더 혼란스럽게합니다.

요약:

  • 소위 "as-if 규칙"은 구현에 대한 제약을 완화하지 않습니다.
  • 고유 한 방언을 얻기 위해 가시적 동작 (외부 세계와의 상호 작용을 위해 구성된 실행 추적)이라는 용어로 지정된 프로그래밍 언어에서 as-if 규칙을 제거 할 수 없습니다.
  • 가시적 동작에 대해 지정되지 않은 프로그래밍 언어에는 as-if 규칙을 추가 할 수 없습니다.

사람들이 내가 틀렸다고 생각하고 뚜렷한 "규칙"이있는 경우 "규칙"없이 C ++ (방언)의 변형을 설명하지 않는 이유는 무엇입니까? C ++ 사양은 무엇을 의미합니까? 컴파일러가 준수하는지 여부를 알 수는 없습니다. 또는 준수를 정의 할 수도 있습니다.
curiousguy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.