Analyzability (since C11)
C 언어의 이 선택적 확장은 일부 형태의 정의되지 않은 동작을 실행할 때 발생할 수 있는 잠재적 결과를 제한하여, 해당 프로그램의 정적 분석 효율성을 향상시킵니다. 분석 가능성은 미리 정의된 매크로 상수 __STDC_ANALYZABLE__ 가 컴파일러에 의해 정의된 경우에만 활성화됨이 보장됩니다.
컴파일러가 분석 가능성을 지원하는 경우, 동작이 정의되지 않은 모든 언어 또는 라이브러리 구성은 임계(critical) 및 제한된(bounded) 정의되지 않은 동작으로 추가 분류되며, 모든 제한된 UB 사례의 동작은 아래에 명시된 대로 제한됩니다.
목차 |
치명적 미정의 동작
크리티컬 UB(Critical UB)는 임의의 객체 범위를 벗어난 메모리 쓰기 또는 휘발성 메모리 읽기를 수행할 수 있는 정의되지 않은 동작입니다. 크리티컬 정의되지 않은 동작을 포함하는 프로그램은 보안 공격에 취약할 수 있습니다.
다음의 정의되지 않은 동작만이 중요합니다:
- 수명이 끝난 객체에 접근 (lifetime) (예: 댕글링 포인터를 통한 접근)
- 선언이 호환되지 않는 객체에 쓰기 작업 수행
- 가리키는 함수의 타입과 호환되지 않는 함수 포인터를 통한 함수 호출
- lvalue 표현식 이 평가되었으나 객체를 지정하지 않는 경우
- 문자열 리터럴 수정 시도
- 역참조 가 유효하지 않은(null, 미정의 등) 또는 범위를 벗어난 포인터인 경우
- 비-const 포인터를 통한 const 객체 수정
- 유효하지 않은 인자로 표준 라이브러리 함수나 매크로 호출
- 예상치 못한 인자 타입으로 가변 인자 표준 라이브러리 함수 호출 (예: 변환 지정자와 타입이 일치하지 않는 인자로 printf 호출)
- longjmp 가 호출 스코프 상에 setjmp 가 없거나, 스레드를 가로지르거나, VM 타입 스코프 내에서 수행된 경우
- free 또는 realloc 으로 해제된 포인터 사용
- 문자열 또는 와이드 문자열 라이브러리 함수가 배열 범위를 벗어나 접근하는 경우
제한된 정의되지 않은 동작
Bounded UB(범위가 제한된 정의되지 않은 동작)는 불법 메모리 쓰기를 수행할 수 없는 정의되지 않은 동작으로, 트랩(trap)이 발생할 수 있고 불확정 값(indeterminate values)을 생성하거나 저장할 수 있습니다.
- 명시적으로 중요(critical)로 분류되지 않은 모든 미정의 동작은 제한적(bounded)입니다, 포함하여
-
- 다중 스레드 데이터 경쟁
- 자동 저장 기간을 가진 미정의 값 사용
- strict aliasing 위반
- 정렬되지 않은 객체 접근
- 부호 있는 정수 오버플로우
- 비순차적 부작용 이 동일한 스칼라를 수정하거나 동일한 스칼라를 수정 및 읽기
- 부동 소수점에서 정수로 또는 포인터에서 정수로의 변환 오버플로우
- 비트 시프트 연산에서 음수 또는 과도한 비트 수로 시프트
- 정수 나눗셈 에서 0으로 나누기
- void 표현식 사용
- 정확히 겹치지 않는 객체의 직접 할당 또는 memcpy 수행
- restrict 위반
- 기타.. 핵심 목록에 포함되지 않은 모든 미정의 동작
참고 사항
경계가 지정된 정의되지 않은 동작은 특정 최적화를 비활성화합니다: 분석 가능성이 활성화된 상태로 컴파일하면 소스 코드의 인과관계가 보존되며, 이는 그렇지 않을 경우 정의되지 않은 동작으로 인해 위반될 수 있습니다 .
분석 가능성 확장은 트랩이 발생할 때 런타임 제약 처리기 가 호출되는 것을 구현 정의 동작의 한 형태로 허용합니다.
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 6.10.10.4/1 조건부 기능 매크로 (p: 188-189)
-
- 부록 L 분석 가능성 (p: 672-673)
- C17 표준 (ISO/IEC 9899:2018):
-
- 6.10.8.3/1 조건부 기능 매크로 (p: 128-129)
-
- 부록 L 분석 가능성 (p: 473-474)
- C11 표준 (ISO/IEC 9899:2011):
-
- 6.10.8.3/1 조건부 기능 매크로 (p: 177)
-
- 부록 L 분석 가능성 (p: 652-653)