Namespaces
Variants

unreachable

From cppreference.net
定義済みヘッダー <stddef.h>
#define unreachable() /* see below */
(C23以降)

関数形式マクロ unreachable void 式に展開されます。 unreachable ( ) を実行すると 未定義動作 が発生します。

実装はこれを使用して、到達不能なコード分岐を最適化により除去する(通常、最適化ビルドで)か、それらの実行を防止するためにトラップする(通常、デバッグビルドで)ことがあります。

目次

実装例

// 可能であればコンパイラ固有の拡張機能を使用
#ifdef __GNUC__ // GCC, Clang, ICC
#define unreachable() (__builtin_unreachable())
#elifdef _MSC_VER // MSVC
#define unreachable() (__assume(false))
#else
// 拡張機能が使用されない場合でも、空の関数本体とnoreturn属性によって未定義動作が発生する
// unreachable_implの外部定義は、C言語でのインライン関数の規則により、別の翻訳単位で出力する必要がある
[[noreturn]] inline void unreachable_impl() {}
#define unreachable() (unreachable_impl())
#endif

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
struct Color { uint8_t r, g, b, a; };
struct ColorSpan { struct Color* data; size_t size; };
// 限られたテクスチャサイズのみがサポートされていると仮定
struct ColorSpan allocate_texture(size_t xy)
{
    switch (xy)
    {
    case 128: [[fallthrough]];
    case 256: [[fallthrough]];
    case 512:
    {
        /* ... */
        struct ColorSpan result = {
            .data = malloc(xy * xy * sizeof(struct Color)),
            .size = xy * xy
        };
        if (!result.data)
            result.size = 0;
        return result;
    }
    default:
        unreachable();
    }
}
int main(void)
{
    struct ColorSpan tex = allocate_texture(128); // OK
    assert(tex.size == 128 * 128);
    struct ColorSpan badtex = allocate_texture(32);  // 未定義動作
    free(badtex.data);
    free(tex.data);
}

出力例:

Segmentation fault

関連項目

C++ ドキュメント for unreachable
翻訳内容: - "C++ documentation" → "C++ ドキュメント" - "for" → "for"(C++文脈で使用されるため、そのまま保持) - "unreachable" → "unreachable"(C++固有の用語のため、翻訳せず保持) HTMLタグ、属性、およびC++固有の用語はすべて原文のまま保持されています。

外部リンク

1. GCC ドキュメント: __builtin_unreachable
2. Clang ドキュメント: __builtin_unreachable
3. MSVC ドキュメント: __assume