제로 예외로 나눗셈을 얻지 못하는 이유를 잘 모르겠습니다.
int d = 0;
d /= d;
제로 예외로 나누기를 기대했지만 대신 d == 1
.
왜 d /= d
0으로 나누기 예외가 발생하지 d == 0
않습니까?
제로 예외로 나눗셈을 얻지 못하는 이유를 잘 모르겠습니다.
int d = 0;
d /= d;
제로 예외로 나누기를 기대했지만 대신 d == 1
.
왜 d /= d
0으로 나누기 예외가 발생하지 d == 0
않습니까?
throw
문에 의해 예외가 발생 합니다. 다른 것은 없습니다 (정의되지 않은 행동 영역에 있지 않는 한).
답변:
C ++에는 "0으로 나누기"예외가 없습니다. 관찰중인 동작은 컴파일러 최적화의 결과입니다.
d == 0
) 에서 Undefined Behavior에 대한 조건이 발생하지 않아야한다고 추론합니다.d / d
항상 1이어야합니다.컴파일러가 코드를 약간만 변경하여 "실제"나누기를 0으로 트리거하도록 할 수 있습니다.
volatile int d = 0;
d /= d; //What happens?
이제 질문이 남아 있습니다. 기본적으로 컴파일러가이를 허용하도록 강제 했으므로 어떻게됩니까? 정의되지 않은 동작이지만 이제 컴파일러가이 정의되지 않은 동작을 최적화하는 것을 방지했습니다.
대부분 대상 환경에 따라 다릅니다. 이 소프트웨어 예외를 트리거하지 않습니다,하지만 수 하드웨어 예외를 트리거 (타겟 CPU에 따라 다름) (정수-으로 나누기) 소프트웨어 예외가 잡힐 수있는 전통 방식으로 잡은 할 수 없습니다. 이것은 x86 CPU와 대부분의 다른 (전부는 아닙니다!) 아키텍처의 경우에 해당합니다.
그러나 프로그램 충돌을 허용하는 대신 하드웨어 예외 (발생한 경우)를 처리하는 방법이 있습니다. 적용 가능한 일부 방법에 대해서는이 게시물을 참조하십시오. 예외 잡기 : 0으로 나누기 . 컴파일러마다 다릅니다.
1
은 완벽하게 유효한 모든 것입니다. 14684554를 얻는 것은 컴파일러가 더욱 최적화하기 때문이어야합니다 . 초기 d==0
조건을 전파 하므로 "이것은 1 또는 UB입니다"뿐만 아니라 실제로 "이것은 UB, 기간입니다"라는 결론을 내릴 수 있습니다. 따라서 상수를로드하는 코드를 생성하지 않아도됩니다 1
.
다른 답변을 보완하기 위해 0으로 나누는 것이 정의되지 않은 동작이라는 사실 은 컴파일러가 어떤 일이 발생할 경우 자유롭게 할 수 있음을 의미합니다 .
0 / 0 == 1
그에 따라 최적화 할 수 있습니다 . 그것이 실제로 여기에서 한 것처럼 보입니다.0 / 0 == 42
설정할 수도 d
있습니다.d
이 불확정 하다고 결정할 수 있으므로 변수를 초기화되지 않은 상태로 두어 해당 값은 이전에 할당 된 메모리에 기록 된 값이됩니다. 주석의 다른 컴파일러에서 관찰 된 예상치 못한 값 중 일부는 이러한 컴파일러가 이와 같은 작업을 수행하기 때문에 발생할 수 있습니다.d
컴파일 타임에 알려지지 않았더라도 컴파일러는 여전히 값이 0 이 아니라고 가정하고 그에 따라 코드를 최적화 할 수 있습니다. OP 코드의 특정 경우에, 이것은 단지를 가정 할 때 컴파일러와 효과적으로 구별 할 수 0 / 0 == 1
없지만, 예를 들어 컴파일러는 puts()
in if (d == 0) puts("About to divide by zero!"); d /= d;
이 실행되지 않는다고 가정 할 수도 있습니다 !정수를 0으로 나누는 동작은 C ++ 표준에서 정의되지 않습니다. 예외를 발생시킬 필요 는 없습니다 .
(부동 소수점을 0으로 나누는 것도 정의되지 않지만 IEEE754가 정의합니다.)
당신의 컴파일러는 최적화 d /= d
하고 있습니다. d = 1
이것은 합리적인 선택입니다. 코드에 정의되지 않은 동작이 없다고 가정 할 수 있기 때문에이 최적화를 수행 d
할 수 있습니다. 이는 0 일 수 없습니다.
d
0 일 수 없습니다 "라고 가정하는 것이 합리적이라고 말할 때 컴파일러가 다음 행을 보지 않는다고 가정합니까 int d = 0;
? ?? :)
부스트 세이프 숫자를 사용하여이 경우 (및 기타 경우)에서 코드에서 C ++ 예외를 생성하도록 할 수 있습니다. https://github.com/boostorg/safe_numerics