utility_unreachable

utility_unreachable (std::unreachable 함수)

이 페이지는 C++23에서 추가된 std::unreachable 함수에 대해 설명해요. 이 함수는 특정 지점에서 정의되지 않은 동작(undefined behavior)을 호출해서, 컴파일러가 도달할 수 없는 코드 경로를 최적화하거나 디버그 빌드에서 트랩을 발생시키도록 도와줘요. 주로 switch문의 기본 분기나 예외 상황에서 사용해요.

출처: cppreference

본문

<utility> 헤더에 정의되어 있어요.

<utility> 헤더에 정의됨
[[noreturn]] void unreachable(); (C++23부터)

이 함수는 호출되는 지점에서 정의되지 않은 동작을 일으켜요. 구현체는 이 함수를 이용해 절대 실행되지 않을 코드 분기를 제거하거나(보통 최적화 빌드), 추가 실행을 막기 위해 트랩을 발생시킬 수 있어요(보통 디버그 빌드).

Notes

Feature-test macro 표준 기능
__cpp_lib_unreachable 202202L (C++23) std::unreachable

Possible implementation

[[noreturn]] inline void unreachable() {
    // Uses compiler specific extensions if possible.
    // Even if no extension is used, undefined behavior is still raised by
    // an empty function body and the noreturn attribute.
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
    __assume(false);
#else // GCC, Clang
    __builtin_unreachable();
#endif
}

Example

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <utility>
#include <vector>

struct Color { std::uint8_t r, g, b, a; };

// Assume that only restricted set of texture caps is supported.
void generate_texture(std::vector<Color>& tex, std::size_t xy)
{
    switch (xy)
    {
    case 128: [[fallthrough]];
    case 256: [[fallthrough]];
    case 512: /* ... */
        tex.clear();
        tex.resize(xy * xy, Color{0, 0, 0, 0});
        break;
    default:
        std::unreachable();
    }
}

int main()
{
    std::vector<Color> tex;
    generate_texture(tex, 128); // OK
    assert(tex.size() == 128 * 128);
    generate_texture(tex, 32);  // Results in undefined behavior
}

Possible output:

Segmentation fault

See also

[[assume(expression)]] (C++23) 특정 지점에서 표현식이 항상 true로 평가된다고 명시하는 속성 지정자 [edit]
assume_aligned (C++20) 포인터가 정렬되어 있음을 컴파일러에 알리는 함수 템플릿 [edit]
C 문서의 unreachable
1. GCC 문서: __builtin_unreachable
2. Clang 문서: __builtin_unreachable
3. MSVC 문서: __assume

더 알아보기 (Learn more)

cppreference