0으로 평가되지 않은 나눗셈은 정의되지 않은 동작입니까?
다음 코드에 대해 일부 동료와 의견이 일치하지 않습니다.
int foo ( int a, int b )
{
return b > 0 ? a / b : a;
}
이 코드가 정의되지 않은 동작을 나타내나요?
편집 : 불일치는 b > 0
검사가 최적화 된 지나치게 열망하는 최적화 컴파일러에서 버그로 보이는 것에서 시작 되었습니다.
아니.
N4140의 인용문 :
§5.16 [expr.cond] / 1
조건식은 오른쪽에서 왼쪽으로 그룹화됩니다. 첫 번째 표현식은 상황에 따라 bool로 변환됩니다. 평가되고 참이면 조건식의 결과는 두 번째 식의 값이고 그렇지 않으면 세 번째 식의 값입니다. 두 번째 및 세 번째 식 중 하나만 평가 됩니다.
더욱이:
§5 [expr] / 4
식을 평가하는 동안 결과가 수학적으로 정의되지 않았거나 해당 유형에 대한 표현 가능한 값 범위에 있지 않으면 동작이 정의되지 않습니다.
이것은 분명히 여기서 일어나지 않습니다. 같은 단락은 메모에서 명시 적으로 0으로 나누기를 언급하며 비 규범 적이지만이 상황과 관련이 있음을 더욱 명확하게합니다.
[참고 : 대부분의 기존 C ++ 구현은 정수 오버플로를 무시합니다. 0으로 나누기 처리, 제로 제수를 사용하여 나머지 형성, 모든 부동 소수점 예외는 기계마다 다르며 일반적으로 라이브러리 함수로 조정 가능합니다. —end note]
위의 요점을 뒷받침하는 상황 적 증거도 있습니다. 조건부 연산자는 조건부로 동작을 정의하지 않는 데 사용됩니다.
§8.5 [dcl.init] /12.3
int f(bool b) { unsigned char c; unsigned char d = c; // OK, d has an indeterminate value int e = d; // undefined behavior return b ? d : 0; // undefined behavior if b is true }
위의 예에서를 사용 d
하여 초기화 int
(또는 unsigned char
)가 정의되지 않았습니다. 그러나 UB 브랜치가 평가되는 경우에만 UB가 발생한다는 것이 명확하게 명시되어 있습니다.
언어 변호사의 관점에서 벗어남 : 이것이 UB 일 수 있다면, 제수가 잠재적으로 0이 될 수 있기 때문에 어떤 부문도 UB로 취급 될 수 있습니다. 이것은 규칙의 정신이 아닙니다.
예제 코드에서는 0으로 나누는 방법이 없습니다. 프로세서가를 실행하면 a / b
이미 b > 0
, 따라서 b
0 이 아닌지 확인했습니다 .
그것은 그 경우주의해야 a == INT_MIN
하고 b == -1
, 다음 a/b
정의되지 않은 동작이 너무. 그러나이 경우 조건이 평가되기 때문에 이것은 어쨌든 방지 false
됩니다.
나는 당신이 의미 return b != 0 ? a / b : a;
하고 return b > 0 ? a / b : a;
b가 0보다 작은 경우가 아니라는 것을 정말로 확신하지 못하지만 , 위에서 설명한 조건이 아닌 한 나눗셈은 여전히 유효합니다.
이 코드가 정의되지 않은 동작을 나타내나요?
아뇨. 표현식
return b > 0 ? a / b : a;
다음과 같다
if(b > 0)
return a/b; // this will be executed only when b is greater than 0
else
return a;
b
이보다 큰 경우 에만 분할이 수행됩니다 0
.
이것이 UB라면
if(a != null && *a == 42)
{
.....
}
그리고 ifs, ands 및 ors의 순서는 명확하게 이러한 유형의 구성을 허용하도록 설계되었습니다. 동료들이 그것에 대해 논쟁 할 것이라고 상상할 수 없습니다.
참고 URL : https://stackoverflow.com/questions/40172606/is-unevaluated-division-by-0-undefined-behavior
'programing' 카테고리의 다른 글
명령 줄에서 log4j 수준을 어떻게 설정합니까? (0) | 2020.12.01 |
---|---|
C #에서 파서를 작성하는 방법? (0) | 2020.12.01 |
C # 리틀 엔디안 또는 빅 엔디안? (0) | 2020.11.30 |
Emacs Org-Mode 내보내기에서 밑줄-구독 비활성화 (0) | 2020.11.30 |
HTML 코드를 트리거하지 않는 꺾쇠 괄호 (<) (0) | 2020.11.30 |