Namespaces
Variants

Constant expressions

From cppreference.net

여러 종류의 표현식이 상수 표현식 으로 알려져 있습니다.

목차

전처리기 상수 표현식

다음 표현식 #if 또는 #elif 은(는) 확장되어야 합니다

문자 상수는 #if -표현식에서 평가될 때, 소스 문자 집합, 실행 문자 집합 또는 기타 구현 정의 문자 집합으로 해석될 수 있습니다.

#if 표현식에서의 정수 연산은 부호 있는 타입에 대해서는 intmax_t 의 의미론을 사용하고, 부호 없는 타입에 대해서는 uintmax_t 의 의미론을 사용하여 수행됩니다.

(C99부터)

정수 상수 표현식

정수 상수 표현식은 오직 다음으로만 구성된 표현식입니다.

  • _Alignof (C23 이전) alignas (C23 이후) 연산자
(C11 이후)
  • 정수 타입이거나 산술 타입이며 캐스트의 직접 피연산자인 명명된 및 복합 리터럴 상수
(C23부터)

정수 상수 표현식은 컴파일 타임에 평가됩니다. 다음 컨텍스트에서는 정수 상수 표현식 으로 알려진 표현식이 필요합니다:

(C99부터)
(C11부터)
  • 비트 정밀 정수 형식의 비트 수 N ( _BitInt ( N ) )
(C23부터)

정적 초기화자

정적 및 스레드 지역 초기화 에서 객체의 저장 기간 을 갖는 또는 constexpr 저장 클래스 지정자로 선언된 (C23부터) 객체의 초기화에 사용되는 표현식은 문자열 리터럴이거나 다음 중 하나일 수 있는 표현식이어야 합니다

1) 산술 상수 표현식(arithmetic constant expression) , 이는 다음으로 구성된 임의의 산술 타입 표현식입니다
(C11부터)
  • 산술 타입의 명명된 또는 복합 리터럴 상수(named or compound literal constants)
(C23부터)
2) 널 포인터 상수 (예: NULL ).
3) address constant expression , 즉
  • null pointer
  • lvalue 가 정적 storage duration 을 가진 객체 또는 함수 지정자를 가리키는 경우, 다음 방법 중 하나로 포인터로 변환된 것
  • 단항 주소 연산자를 사용하여
  • 정수 상수를 포인터로 캐스팅하여
  • 배열-포인터 또는 함수-포인터 암시적 conversion 을 통해
4) address constant expression of some complete object type, plus or minus an integer constant expression .
5) 명명된 상수(named constant) 로서, 다음 중 하나인 식별자:
  • 열거형 상수
  • 미리 정의된 상수 ( true , false , nullptr 중 하나)
  • 저장류 지정자 constexpr 로 선언되고 객체 타입을 가진 경우
또는 구조체나 공용체 타입의 명명된 상수에 대해, 심지어 재귀적으로라도 . 멤버 접근 연산자를 적용하는 후위 표현식.
6) 복합 리터럴 상수(compound literal constant) 로서, 다음 중 하나:
  • 저장류 지정자 constexpr 가 있는 복합 리터럴
  • 구조체나 공용체 타입의 복합 리터럴 상수에 대해, 심지어 재귀적으로라도 . 멤버 접근 연산자를 적용하는 후위 표현식.

구조체 또는 공용체 상수 는 각각 구조체나 공용체 타입을 가진 명명된 상수 또는 복합 리터럴 상수입니다. 멤버 접근 연산자 . 가 공용체 상수의 멤버에 접근하는 경우, 접근된 멤버는 공용체 상수의 초기화자에 의해 초기화된 멤버와 동일해야 합니다.

(C23 이후)
7) 구현체에서 허용하는 다른 형식 중 하나의 상수 표현식.

정수 상수 표현식과 달리, 정적 초기화 표현식은 컴파일 타임에 평가될 필요가 없습니다; 컴파일러는 이러한 초기화 코드를 프로그램 시작 전에 호출되는 실행 코드로 변환할 자유를 가집니다.

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++ 문서 참조: 상수 표현식