名前空間
変種
操作

unreachable

From cppreference.com
< c‎ | program
ヘッダー <stddef.h> で定義
#define unreachable() /* 以下を参照 */
(C23以降)

関数ライクなマクロunreachableは、void式の展開となります。unreachable()を実行すると、未定義の動作が発生します。

実装によっては、これを使用して到達不可能なコードブランチを最適化(通常は最適化ビルドで)したり、さらなる実行を防ぐためにトラップ(通常はデバッグビルドで)したりすることができます。

目次

[編集] 実装例

// Uses compiler specific extensions if possible.
#ifdef __GNUC__ // GCC, Clang, ICC
 
#define unreachable() (__builtin_unreachable())
 
#elifdef _MSC_VER // MSVC
 
#define unreachable() (__assume(false))
 
#else
// Even if no extension is used, undefined behavior is still raised by
// the empty function body and the noreturn attribute.
 
// The external definition of unreachable_impl must be emitted in a separated TU
// due to the rule for inline functions in 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; };
 
// Assume that only restricted set of texture caps is supported.
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);  // Undefined behavior
 
    free(badtex.data);
    free(tex.data);
}

実行結果の例

Segmentation fault

[編集] 関連項目

C++ドキュメント (unreachable)

[編集] 外部リンク

1.  GCCドキュメント: __builtin_unreachable
2.  Clangドキュメント: __builtin_unreachable
3.  MSVCドキュメント: __assume
English 日本語 中文(简体) 中文(繁體)