C ++에는 상수 표현식의 매우 깔끔한 속성이 있습니다. 평가에는 정의되지 않은 동작 ( 7.7.4.7 ) 이있을 수 없습니다 .
추상 기계의 규칙 ([intro.execution])에 따라 e의 평가가 다음 중 하나를 평가하지 않는 한, 표현식 e는 핵심 상수 표현식입니다.
...
이 문서의 [intro] ~ [cpp]에 지정된대로 정의되지 않은 동작을 갖는 연산 [참고 : 예를 들어 부호있는 정수 오버플로 ([expr.prop]), 특정 포인터 산술 ([expr.add]) 포함, 0으로 나누기, 또는 특정 시프트 연산 – 끝 참고];
의 값을 저장하려고 13!
A가에 constexpr int
참으로 멋진 컴파일 오류를 얻을 수를 :
constexpr int f(int n)
{
int r = n--;
for (; n > 1; --n) r *= n;
return r;
}
int main()
{
constexpr int x = f(13);
return x;
}
산출:
9:19: error: constexpr variable 'x' must be initialized by a constant expression
constexpr int x = f(13);
^ ~~~~~
4:26: note: value 3113510400 is outside the range of representable values of type 'int'
for (; n > 1; --n) r *= n;
^
9:23: note: in call to 'f(3)'
constexpr int x = f(13);
^
1 error generated.
(BTW가 왜 '(f) (f)'(f)에 대한 호출입니까? '
그럼, 제거 constexpr
에서 x
,하지만 할 f
을 consteval
. 문서 에 따르면 :
consteval-함수가 즉각적인 함수임을 지정합니다. 즉, 함수를 호출 할 때마다 컴파일 타임 상수가 생성되어야합니다.
그러한 프로그램이 다시 컴파일 오류를 일으킬 것으로 예상합니다. 그러나 대신 프로그램은 UB로 컴파일하고 실행합니다 .
왜 그런 겁니까?
UPD : 의견 제시 자들은 이것이 컴파일러 버그라고 제안했습니다. 나는 그것을보고했다 : https://bugs.llvm.org/show_bug.cgi?id=43714
in call to 'f(3)'
- 이건 이상해! 전의.f(123)
clang 을 넣으면 에 대해 경고합니다in call to 'f(119)'
.