Constant expressions
여러 종류의 표현식이 상수 표현식 으로 알려져 있습니다.
목차 |
전처리기 상수 표현식
다음 표현식
#if
또는
#elif
은(는) 확장되어야 합니다
문자 상수는
#if
-표현식에서 평가될 때, 소스 문자 집합, 실행 문자 집합 또는 기타 구현 정의 문자 집합으로 해석될 수 있습니다.
|
|
(C99부터) |
정수 상수 표현식
정수 상수 표현식은 오직 다음으로만 구성된 표현식입니다.
- 연산자 중 대입 , 증가, 감소 , 함수 호출 , 또는 콤마 연산자를 제외한 연산자들. 단, 캐스트 연산자는 산술 타입을 정수 타입으로만 변환할 수 있으며, sizeof 연산자의 피연산자 일부인 경우는 예외 , _Alignof (C11부터) (C23 이전) , alignas (C23부터) 또는 typeof/typeof_unqual (C23부터) 연산자의 피연산자인 경우는 제외.
- 정수 상수
- 열거형 상수
- 문자 상수
- 부동 소수점 상수 , 단 정수 타입으로의 캐스트 연산자에 바로 사용되는 경우에만
-
sizeof연산자 (피연산자가 VLA가 아닌 경우) (C99부터)
|
(C11 이후) |
|
(C23부터) |
정수 상수 표현식은 컴파일 타임에 평가됩니다. 다음 컨텍스트에서는 정수 상수 표현식 으로 알려진 표현식이 필요합니다:
|
(C99부터) |
|
(C11부터) |
|
(C23부터) |
정적 초기화자
정적 및 스레드 지역 초기화 에서 객체의 저장 기간 을 갖는 또는 constexpr 저장 클래스 지정자로 선언된 (C23부터) 객체의 초기화에 사용되는 표현식은 문자열 리터럴이거나 다음 중 하나일 수 있는 표현식이어야 합니다
-
- 연산자(operators) 중 대입(assignment) , 증가/감소(increment, decrement) , 함수 호출(function-call) , 또는 쉼표(comma) 를 제외한 연산자. 단, 캐스트(cast) 연산자는 산술 타입을 다른 산술 타입으로 변환하는 경우에만 허용되며, sizeof , _Alignof (C11부터) (C23 이전) , alignof (C23부터) 또는 typeof/typeof_unqual (C23부터) 연산자의 피연산자 일부인 경우는 예외
- 정수 상수(integer constants)
- 부동 소수점 상수(floating constants)
- 열거형 상수(enumeration constants)
- 문자 상수(character constants)
-
sizeof연산자 (피연산자가 VLA가 아닌 경우) (C99부터)
| (C11부터) |
|
(C23부터) |
-
- null pointer
- lvalue 가 정적 storage duration 을 가진 객체 또는 함수 지정자를 가리키는 경우, 다음 방법 중 하나로 포인터로 변환된 것
-
- 단항 주소 연산자를 사용하여
- 정수 상수를 포인터로 캐스팅하여
- 배열-포인터 또는 함수-포인터 암시적 conversion 을 통해
|
5)
명명된 상수(named constant)
로서, 다음 중 하나인 식별자:
.
멤버 접근 연산자를 적용하는 후위 표현식.
6)
복합 리터럴 상수(compound literal constant)
로서, 다음 중 하나:
구조체 또는 공용체 상수
는 각각 구조체나 공용체 타입을 가진 명명된 상수 또는 복합 리터럴 상수입니다. 멤버 접근 연산자
|
(C23 이후) |
정수 상수 표현식과 달리, 정적 초기화 표현식은 컴파일 타임에 평가될 필요가 없습니다; 컴파일러는 이러한 초기화 코드를 프로그램 시작 전에 호출되는 실행 코드로 변환할 자유를 가집니다.
static int i = 2 || 1 / 0; // i를 값 1로 초기화
|
이 섹션은 불완전합니다
이유: 다른 미니 예시들 |
부동 소수점 정적 초기화자의 값은 런타임에 동일한 표현식을 실행한 값보다 정확도가 낮은 경우는 절대 없지만, 더 나을 수는 있습니다.
부동 소수점 상수 표현식
정적 초기화자에서 사용되지 않는 부동 소수점 타입의 산술 상수 표현식은 항상 런타임 중인 것처럼 평가되며, 현재 반올림 모드 (만약 FENV_ACCESS 가 켜져 있을 경우)의 영향을 받고 math_errhandling 에 지정된 대로 오류를 보고합니다.
void f(void) { #pragma STDC FENV_ACCESS ON static float x = 0.0 / 0.0; // 정적 초기화: 예외를 발생시키지 않음 float w[] = { 0.0 / 0.0 }; // 예외를 발생시킴 float y = 0.0 / 0.0; // 예외를 발생시킴 double z = 0.0 / 0.0; // 예외를 발생시킴 }
참고 사항
표현식이 해당 타입으로 표현할 수 없는 값으로 평가될 경우, 상수 표현식으로 사용할 수 없습니다.
구현체는 다른 형태의 상수 표현식을 허용할 수도 있습니다. 그러나 이러한 상수 표현식은 정수 상수 표현식, 산술 상수 표현식, 또는 주소 상수 표현식으로 간주되지 않으며, 따라서 이러한 종류의 상수 표현식이 필요한 문맥에서 사용될 수 없습니다. 예를 들어, int arr [ ( int ) + 1.0 ] ; 는 VLA를 선언합니다.
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 6.6 상수 표현식 (p: 95-96)
- C17 표준 (ISO/IEC 9899:2018):
-
- 6.6 상수 표현식 (p: 76-77)
- C11 표준 (ISO/IEC 9899:2011):
-
- 6.6 상수 표현식 (p: 106-107)
- C99 표준 (ISO/IEC 9899:1999):
-
- 6.6 상수 표현식 (p: 95-96)
- C89/C90 표준 (ISO/IEC 9899:1990):
-
- 3.4 CONSTANT EXPRESSIONS
참고 항목
|
C++ 문서
참조:
상수 표현식
|