アサーション

Unreal Engine4 のアサーション機能のリファレンスです。

Choose your operating system:

Windows

macOS

Linux

および C++ プログラミングでは、 assert が開発中の予期しない条件や無効なランタイム条件の検出と診断に役立ちます。このような条件では、多くの場合、ポインターが null でないこと、除数が 0 でないこと、関数が再帰的に実行されていないこと、またはコードが必要とするその他の重要な前提条件を検証しますが、毎回検証を実行するのは非効率的です。また、 assert は以降のティックで必要となるオブジェクトを削除してしまうといったような、実際のクラッシュを発生させる前の遅延クラッシュを引き起こすバグを検出し、デベロッパーが最終的なクラッシュの根本原因を検出するのに役立つこともあります。 assert の主な特徴は、シッピング コードには存在しないということです。つまり、リリースされた製品のパフォーマンスに影響を与えることはなく、副作用も一切ありません。 assert の仕組みを簡単に説明すると、「アサートされた」ものはすべて true である必要があり、true でなければプログラムの実行が停止します。

Unreal Engine 4 (UE4) では、同等の 3 種類の assert ファミリ、 check verify ensure を使用できます。これらの機能を基盤として使用しているコードを確認する場合は、「 Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h 」に該当するマクロがあります。各マクロのビヘイビアはわずかに異なるものの、どのマクロも開発時に使用する診断ツールと同じ一般的な役割を果たします。

Check

Check ファミリは基本の assert に最も近く、このファミリのメンバーは最初のパラメータの値が false と評価されると実行を停止します。また、シッピング ビルドではデフォルトで実行されません。使用可能な Check マクロは次のとおりです。

マクロ

パラメータ

ビヘイビア

check または checkSlow

Expression

Expression が false の場合、実行を停止します

checkf または checkfSlow

Expression , FormattedText , ...

Expression が false の場合、実行を停止し、ログに FormattedText を出力します

checkCode

Code

1 回実行される do-while ループ構造内で Code を実行します。主に、別の Check に必要な情報を準備するのに役立ちます。

checkNoEntry

(なし)

check(false) と同様に、この行がヒットした場合実行を停止します。ただし、これは到達不能なコード パスを対象としています

checkNoReentry

(なし)

この行が 2 回以上ヒットした場合、実行を停止します

checkNoRecursion

(なし)

スコープを離れることなくこの行が 2 回以上ヒットした場合、実行を停止します

unimplemented

(なし)

check(false) と同様に、この行がヒットした場合は実行を停止します、ただし、これはオーバーライドされるべき仮想関数および呼び出されるべきではない仮想関数を対象としています

Check マクロは、デバッグ、開発、テスト、およびシッピング エディタ ビルドで動作します。ただし、末尾が「Slow」であるマクロは除きます。このマクロはデバッグ ビルドでのみ動作します。true の値 (通常 1 ) を保持するように USE_CHECKS_IN_SHIPPING を定義すると、Check マクロはすべてのビルドで動作します。これは、Check マクロ内のコードが値を変更していたり、追跡困難なシッピングのみのバグがあるという疑いがあり、既存の Check マクロでキャッチされるという疑いがある場合に役立ちます。プロジェクトのシッピングでは、 USE_CHECKS_IN_SHIPPING をデフォルト値である 0 に設定する必要があります。

Verify

Verify ファミリは、ほとんどのビルドで Check ファミリと同一の動作を行います。ただし、Check マクロが無効になっているビルドでも、Verify マクロは式を評価します。診断チェックとは別に式を実行する必要がある場合にのみ、Verify マクロを使用する必要があります。例えば、アクションを実行し、そのアクションの成否を示す bool 値を返す関数がある場合は、Check ではなく Verify を使用して、アクションが成功したことを確認する必要があります。これは、シッピング ビルドでは Verify は戻り値を無視して、引き続きアクションを実行するためです。ただし、Check はシッピング ビルドで関数をまったく呼び出さないため、ビヘイビアが異なります。

マクロ

パラメータ

ビヘイビア

verify または verifySlow

Expression

Expression が false の場合、実行を停止します

verifyf または verifyfSlow

Expression , FormattedText , ...

Expression が false の場合、実行を停止し、ログに FormattedText を出力します

Verify マクロは、デバッグ、開発、テスト、およびシッピング エディタ ビルドで完全に動作します。ただし、末尾が「Slow」であるマクロは除きます。これは、デバッグ ビルドでのみ動作します。true の値 (通常 1 ) を保持するために USE_CHECKS_IN_SHIPPING を定義すると、このビヘイビアはオーバーライドされます。他のどの場合でも、Verify マクロは式の評価は行いますが、実行の停止や、テキストのログ出力は行いません。

Ensure

Ensure ファミリは Verify ファミリに似ていますが、致命的ではないエラーで動作します。つまり、Ensure マクロの式が false と評価された場合、エンジンはクラッシュ レポート機能に通知するものの、実行は継続します。クラッシュ レポート機能のフラッディングを回避するために、Ensure マクロでは、エンジンまたはエディタ セッションごとに 1 度のみレポートします。ユース ケースで、式が false と評価されるたびに、Ensure マクロで報告する必要がある場合は、「Always」バージョンのマクロを使用します。

マクロ

パラメータ

ビヘイビア

ensure

Expression

Expression が初めて false になったときにクラッシュ レポート機能に通知します

ensureMsgf

Expression , FormattedText , ...

Expression が初めて false になったときに、クラッシュ レポート機能に通知し、 FormattedText をログに出力します

ensureAlways

Expression

Expression が false の場合、クラッシュ レポートに通知します

ensureAlwaysMsgf

Expression , FormattedText , ...

Expression が false の場合、クラッシュ レポート機能に通知し、 FormattedText をログに出力します

Ensure マクロはすべてのビルドで式を評価しますが、デバッグ、開発、テスト、およびシッピング エディタのビルドでのみクラッシュ レポート機能に通知します。

使用例:

次の仮定の状況で、Check、Verify、および Ensure がコードの明確化やデバッグの支援に役立つユース ケースを示しています。

// This function should never be called with a null JumpTarget.Halt the program if it happens.
void AMyActor::CalculateJumpVelocity(AActor* JumpTarget, FVector& JumpVelocity)
{
    check(JumpTarget != nullptr);
    // (Compute velocity we need to land on JumpTarget.We are now confident that JumpTarget is non-null.)
}
// This sets the value of Mesh and expects it to be non-null.Halt the program if Mesh is null afterward.
// We use verify instead of check because our expression has a side effect (setting Mesh).
verify((Mesh = GetRenderMesh()) != nullptr);

// This line of code catches a minor error that could happen in the shipping version of the product.

// The error is minor enough that we can handle it without needing to halt execution.
// We may think that we've fixed the bug, but still want to know if it ever happens.
void AMyActor::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);
    // Ensure that bWasInitialized is true before proceeding.If it is false, log that the bug hasn't been fixed yet.
    if (ensureMsgf(bWasInitialized, TEXT("%s ran Tick() with bWasInitialized == false"), *GetActorLabel()))
    {
        // (Do something that requires a properly-initialized AMyActor.)
    }
}
// This code halts if we add a new shape type, but forget to handle it in this switch block.
switch (MyShape)
{
    case EShapes::S_Circle:
        // (Handle circles.)
        break;
    case EShapes::S_Square:
        // (Handle squares.)
        break;
    default:
        // There should be a case for every shape type, so this should never happen.
        checkNoEntry();
        break;
}
// This UObject has a test function, IsEverythingOK, that has no side effects, but returns false if there's a problem.
// If this happens, terminate with a fatal error.
// Because the code has no side effects and only serves a diagnostic purpose, it does not need to run in shipping builds.
checkCode(
    if (!IsEverythingOK())
    {
        UE_LOG(LogUObjectGlobals, Fatal, TEXT("Something is wrong with %s!Terminating."), *GetFullName());
    }
);
// There should never be a cycle in this list, and our program will hang if there is one.However, checking for cycles can be slow, so we only want to do it in debug builds.
checkSlowf(!MyLinkedList.HasCycle(), TEXT("Found a cycle in the list!"));
// (Walk through the list, running some code on each element.)
Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
閉じる