Namespaces
Variants

C++ attribute: assume (since C++23)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

주어진 지점에서 특정 표현식이 항상 true 로 평가된다고 가정하여, 제공된 정보를 기반으로 컴파일러 최적화를 가능하게 합니다.

목차

구문

[ [ assume ( 표현식 ) ] ]
expression - 모든 표현식(괄호로 묶이지 않은 comma expressions 제외)

설명

[ [ assume ] ] 는 오직 null 문 에만 적용될 수 있으며, 다음과 같이 사용됩니다: [ [ assume ( x > 0 ) ] ] ; . 이 문장을 가정(assumption) 이라고 부릅니다.

expression bool 로 문맥적 변환이 이루어지지만 평가되지는 않습니다(여전히 잠재적으로 평가될 수 있는 표현식 입니다).

  • 변환된 expression 이 가정이 나타나는 지점에서 true 로 평가된다면, 가정은 아무런 효과가 없습니다.
  • 그렇지 않으면, 가정의 평가는 런타임-정의되지 않은 동작 을 가집니다.

참고 사항

가정이 성립하지 않을 경우 런타임-정의되지 않은 동작을 유발하므로, 가정은 신중하게 사용되어야 합니다.

이를 올바르게 사용하는 한 가지 방법은 단정문(assertions) 뒤에 가정문(assumptions)을 따르도록 하는 것입니다:

assert(x > 0);     // NDEBUG가 정의되지 않았고 x > 0이 거짓일 때 assertion을 발생시킴
[[assume(x > 0)]]; // NDEBUG가 정의되었을 때 최적화 기회를 제공함

예제

#include <cmath>
void f(int& x, int y)
{
    void g(int);
    void h();
    [[assume(x > 0)]]; // 컴파일러는 x가 양수라고 가정할 수 있음
    g(x / 2); // 더 효율적인 코드가 생성될 수 있음
    x = 3;
    int z = x;
    [[assume((h(), x == z))]]; // 컴파일러는 h 호출 후에도 x가 동일한 값을 가질 것이라고 가정할 수 있음
                               // 이 가정은 h에 대한 호출을 발생시키지 않음
    h();
    g(x); // 컴파일러는 이를 g(3);으로 대체할 수 있음
    h();
    g(x); // 컴파일러는 이를 g(3);으로 대체할 수 없음
          // 가정은 해당 가정이 나타나는 지점에서만 적용됨
    z = std::abs(y);
    [[assume((g(z), true))]]; // 컴파일러는 g(z)가 반환될 것이라고 가정할 수 있음
    g(z); // 위와 아래 가정으로 인해 컴파일러는 이를 g(10);으로 대체할 수 있음
    [[assume(y == -10)]]; // 이 시점에서 y != -10이면 정의되지 않은 동작
    [[assume((x - 1) * 3 == 12)]];
    g(x); // 컴파일러는 이를 g(5);으로 대체할 수 있음
}

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 2924 C++23 가정 위반 시 미정의 동작이 발생함 런타임-미정의 동작이 발생함

참고문헌

  • C++23 표준 (ISO/IEC 14882:2024):
  • 9.12.3 가정 속성 [dcl.attr.assume]

참고 항목

실행 불가능한 지점을 표시합니다
(함수)
contract_assert statement (C++26) 실행 중 내부 조건을 검증합니다

외부 링크

1. Clang 언어 확장 문서: __builtin_assume .
2. Clang 속성 참조 문서: assume .
3. MSVC 문서: __assume 내장 함수.
4. GCC 문서: __attribute__((assume(...))) .