C에서 "-1>>5;"가 지정되지 않은 동작입니까?
C11 § 6.5.7 문단 5:
의 결과
E1 >> E2이라E1E2비트 위치. 만약.E1서명되지 않은 유형이 있거나 다음과 같은 경우E1가 아닌 값을 , 은 호가있 는유음아값가을지, 결의값다몫다부니입분의 몫의 적분 입니다.E1 / 2*^E2부호 있는 유형과 음수 값이 있는 경우 결과 값은 구현 정의됩니다.
그러나 viva64 참조 문서에는 다음과 같이 나와 있습니다.
int B; B = -1 >> 5; // unspecified behavior
GCC에서 이 코드를 실행했는데 항상 출력이 나옵니다.-1.
따라서 표준은 "E1이 부호 있는 유형과 음수 값을 가지고 있다면, 그 결과 값은 구현 정의"라고 말하지만, 그 문서는 다음과 같이 말합니다.-1>>5;지정되지 않은 동작입니다.
그래서, 아이즈-1>>5;C에서 지정되지 않은 동작?어떤 것이 올바른가요?
둘 다 맞습니다.구현 정의 동작은 특정 유형의 지정되지 않은 동작입니다.
"구현 정의 행동"을 정의하는 C 표준의 섹션 3.4.1을 인용합니다.
1 구현 정의 동작
각 구현이 선택 방법을 문서화하는 지정되지 않은 동작
2 구현 정의 동작의 예는 부호 있는 정수가 오른쪽으로 이동할 때 상위 비트의 전파입니다.
섹션 3.4.4에서 "지정되지 않은 동작"을 정의합니다.
1 불특정 다수의 행동
본 국제 표준이 두 가지 이상의 가능성을 제공하고 어떠한 경우에도 선택된 추가 요건을 부과하지 않는 불특정 값의 사용 또는 기타 행동
2 지정되지 않은 동작의 예는 함수에 대한 인수를 평가하는 순서입니다.
GCC의 경우, 작업이 정의되어 있기 때문에 항상 동일한 답변을 얻을 수 있습니다.부호 확장을 통해 음수의 오른쪽 이동을 구현합니다.
GCC 문서에서 다음을 수행합니다.
부호 있는 정수(C90 6.3, C99 및 C116.5)에 대한 일부 비트 단위 작업의 결과입니다.
비트 연산자는 부호 비트와 값 비트를 모두 포함한 값의 표현에 따라 동작하며 부호 비트는 가장 높은 값 비트 바로 위에 있는 것으로 간주됩니다.서명은 부호 확장에 의해 음수에 작용합니다.
으로서, 를 오직 있는 C의 사용하지 .
<<정의되지 않은 바와 같이하지만,-fsanitize=shift)-fsanitize=undefined경우를 에서 이러한 경우를 진단합니다.그들은 또한 지속적인 표현이 필요한 곳에서 진단됩니다.
"불특정 행동"과 "실행 정의"는 모순되지 않습니다.그것은 단지 C 표준이 무엇이 일어나야 하는지 명시하지 않고, 다양한 구현이 그들이 "올바르게" 생각하는 것을 할 수 있다는 것을 의미합니다.
한 컴파일러에서 여러 번 실행하고 동일한 결과를 얻는 것은 특정 컴파일러가 일관성을 유지한다는 것을 의미합니다.다른 컴파일러에서 다른 결과를 얻을 수 있습니다.
구현 정의 동작은 지정되지 않은 동작의 하위 클래스, 즉 표준에 의해 지정되지 않은 동작입니다.
결함 보고서 #154 ~ C89는 구현 정의 행동의 한계가 무엇인지 위원회에 질문했습니다. 위원회는 구현이 원하는 모든 행동을 정의할 수 있으며, 이는 일정할 필요가 없다고 답변합니다.
구현이 해야 할 일은 이 선택이 어떻게 이루어지는지를 문서화하는 것입니다. 이는 준수 구현이 어떻게 결정되는지 알려줄 필요가 없는 불특정 행동의 다른 클래스와는 대조적입니다.아마도 이러한 구현의 대부분이 "랜덤으로", "컴파일러 최적화 수준에 따라" 또는 "로컬 변수에 대한 레지스터 할당에 따라" 텍스트이기 때문일 것입니다.
저는 현재 답변을 전혀 이해하지 못합니다.C 표준은 음의 숫자를 오른쪽으로 이동하는 것이 구현 정의 행동이라고 분명히 말합니다.그것은 다른 것을 의미하는 지정되지 않은 행동이 아닙니다.정확하게 인용한 바와 같이 (C17 6.5.7 §5)
이동 위치입니다 /--/E1 >> E2는 E1의 E2입니다. /---/
E1에 부호 있는 유형과 음수 값이 있으면 결과 값이 구현 정의됩니다.
이는 컴파일러가 동작 방식을 문서화해야 함을 의미합니다.마침표.
실제로: 문서는 컴파일러가 산술 오른쪽 이동을 사용하는지 논리 오른쪽 이동을 사용하는지 알려주어야 합니다.
이는 문서화할 필요가 없는 구현별 동작인 지정되지 않은 동작과는 대조적입니다.지정되지 않은 동작은 다음 두 가지 경우에 사용됩니다.
- 컴파일러 동작이 컴파일러 공급업체가 경쟁업체에 공개하도록 강요해서는 안 되는 구현 비밀일 수 있습니다.
- 컴파일러가 OS 및 RAM 메모리 셀과 같은 기본 세부 정보를 문서화하는 데 번거로움이 없을 때.
예를 들어 컴파일러는 다음과 같은 코드로 평가 순서를 문서화할 필요가 없습니다.
a = f1() + f2();
a += f1() + f2();
하위 표현식이 평가되는 순서를 문서화하면 컴파일러의 내부 표현식 트리와 최적화기가 어떻게 작동하는지에 대한 세부 사항이 드러나게 되며, 이는 컴파일러가 경쟁사보다 더 나은 코드를 생성하거나 더 빨리 컴파일하는 이유를 밝혀줍니다.이것은 원래 C 표준이 작성되었을 때 큰 일이었습니다.요즘에는 그렇지 않습니다. 훌륭한 오픈 소스 컴파일러가 있기 때문에 더 이상 비밀이 아닙니다.
마찬가지로 컴파일러는 이 코드가 출력하는 내용을 문서화할 필요가 없습니다.
int a;
int ptr = &a;
printf("%d", *ptr);
a는 불확실한 값이며 출력은 지정되지 않습니다. 실제로 출력은 이전에 특정 RAM 셀에 저장된 내용에 따라 달라집니다."가비지 값"이라고 부르는 것입니다. ("UB"를 외치기 전에 (왜) 초기화되지 않은 변수 정의되지 않은 동작을 사용하고 있는지 참조하십시오.)
언급URL : https://stackoverflow.com/questions/46777286/is-15-unspecified-behavior-in-c
'programing' 카테고리의 다른 글
| 모든 mysql 테이블 간의 모든 관계를 찾는 방법은 무엇입니까? (0) | 2023.08.27 |
|---|---|
| 특정 순서에 따른 SQL 순서 (0) | 2023.08.27 |
| Angular 5 및 재료 - 스낵바 구성 요소에서 배경색 변경 방법 (0) | 2023.08.27 |
| if-문에 여러 조건 결합 (0) | 2023.08.27 |
| UIBarButtonItem: target-action이 작동하지 않습니까? (0) | 2023.08.27 |