Unreal Engine 4 アサーション機能リファレンス
C および C++ プログラミングでは、assert
開発中に異常または無効な実行時状態を検出および診断するのに役立ちます。これらの条件は通常、ポインターが null ではないか、除数が 0 ではないか、関数が再帰的に実行されないか、またはコードで必要なその他の重要な前提条件をチェックします。しかし、チェックするたびにそれは非常に非効率になります。場合によっては、assert
将来のティックで必要なオブジェクトの削除など、クラッシュの原因となったバグが遅延クラッシュが発生する前に発見され、開発者がクラッシュの根本原因を見つけるのに役立ちます。assert
の重要な機能の 1 つは、リリース コードには存在しないことです。つまり、リリース製品のパフォーマンスに影響を与えず、副作用もありません。最も assert
単純な理解は、「アサーション」が true でなければならない、そうでない場合はプログラムの実行が停止する、ということです。
Unreal Engine 4 (UE4) は 、 、 、 の assert
3 つの異なるファミリを提供します。これらの関数の背後にあるコードを調べるには、 関連するマクロが次の場所にあります。各機能の動作は若干異なりますが、これらはすべて、ほぼ同じ目標を持って開発中に使用される診断ツールです。check
verify
ensure
Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h
チェック
Check ファミリは assert
、最初の引数が false と評価されると実行を停止し、デフォルトではリリース ビルドでは実行されないため、基本に最も近いものです。次のチェック マクロが使用可能です。
大きい |
パラメータ |
行動 |
---|---|---|
|
|
falseの場合 |
|
|
falseの場合 |
|
|
一度実行される do-while ループ構造で実行します |
|
(なし) |
この行がヒットした場合に実行を停止します。 と似ています |
|
(なし) |
この行が複数回ヒットした場合、実行を停止します |
|
(なし) |
スコープを離れることなくこの行が複数回ヒットした場合は実行を停止します |
|
(なし) |
この行にヒットした場合は、実行を停止します。 と似ています |
デバッグ、開発、テスト、および出荷エディター ビルドで実行されるマクロを確認します (デバッグ ビルドでのみ実行される「Slow」で終わるマクロを除く)。Check マクロがすべてのバージョンで機能するようにするには、USE_CHECKS_IN_SHIPPING
値 true (通常は ) を保持するように 定義します 。1
この方法は、次のような状況で非常に役立ちます: Check マクロ内のコードが値を変更しているのではないかと疑う場合、リリース バージョンにのみ存在し追跡が難しいバグを見つけるが、既存の Check マクロでこれらのバグを検出できると考えられる場合。プロジェクトの公開時に USE_CHECKS_IN_SHIPPING
デフォルト値に設定する 必要があります0
。
確認する
ほとんどのバージョンでは、Verify ファミリは Check ファミリと同じように動作します。ただし、Check マクロが無効になっているバージョンでも、Verify マクロはその式を評価します。つまり、Verify マクロは、その式を診断チェックとは独立して実行する必要がある場合にのみ使用する必要があります。たとえば、関数が操作を実行し、 その操作が成功したかどうかを示すために戻る場合は、Check ではなく Verify を使用して、操作が成功したことを確認します。リリース ビルドでは Verify は戻り値を無視しますが、操作は実行するためです。また、Check はリリース ビルドでは関数をまったく呼び出さないため、動作が異なります。bool
大きい |
パラメータ |
行動 |
---|---|---|
|
|
falseの場合 |
|
|
falseの場合 |
マクロがデバッグ、開発、テスト、および出荷エディター ビルドで完全に実行されることを確認します (デバッグ ビルドでのみ実行される「Slow」で終わるマクロを除く)。USE_CHECKS_IN_SHIPPING
true (通常は ) の値を保持するように 定義し 1
、この動作をオーバーライドします。それ以外の場合はすべて、Verify マクロは式を評価しますが、実行を停止したり、テキストをログに出力したりしません。
Ensure
Ensure ファミリは Verify ファミリに似ていますが、致命的ではないエラーの場合に使用できます。これは、Ensure マクロの式が false と評価された場合、エンジンはクラッシュ レポーターに通知しますが、実行は継続されることを意味します。クラッシュ レポーターへの通知が多すぎるのを避けるため、Ensure マクロはエンジンまたはエディターセッションごとに1 回だけレポートされます。実際の状況で、式が false と評価されるたびに Ensure マクロがレポートする必要がある場合は、マクロの「Always」バージョンを使用してください。
大きい |
パラメータ |
行動 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Ensure マクロはすべてのビルドで式を評価しますが、クラッシュ レポーターに接続するのは、デバッグ、開発、テスト、および出荷エディターのビルドでのみです。
例
次の仮説的なシナリオは、Check、Verify、Ensure がコードを明確にしたり、デバッグを支援したりできるいくつかの使用例を示しています。
// 决不可使用空JumpTarget调用此函数。若发生此情况,须停止程序。
void AMyActor::CalculateJumpVelocity(AActor* JumpTarget, FVector& JumpVelocity)
{
check(JumpTarget != nullptr);
//(计算在JumpTarget上着陆所需的速度。现在可确定JumpTarget为非空。)
}
// 这将设置Mesh的值,并预计为非空值。若之后Mesh的值为空,则停止程序。
// 使用Verify而非Check,因为表达式存在副作用(设置网格体)。
verify((Mesh = GetRenderMesh()) != nullptr);
// 这行代码捕获了在产品发布版本中可能出现的小错误。
// 此错误较小,无需停止执行便可解决。
// 虽然该bug已修复,但开发者仍然希望了解之前是否曾经出现过此bug。
void AMyActor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
// 确保bWasInitialized为true,然后再继续。若为false,则在日志中记录该bug尚未修复。
if (ensureMsgf(bWasInitialized, TEXT("%s ran Tick() with bWasInitialized == false"), *GetActorLabel()))
{
//(执行一些需要已正确初始化AMyActor的操作。)
}
}
// 若添加新形状类型,但忘记在此切换块中处理,则此代码将停止。
switch (MyShape)
{
case EShapes::S_Circle:
//(处理圆圈。)
break;
case EShapes::S_Square:
//(处理方块。)
break;
default:
// 每种形状类型都应有相应情况,因此这种情况不应该发生。
checkNoEntry();
break;
}
// 此UObject拥有测试函数IsEverythingOK,没有副作用,若出现问题则返回false。
// 若发生这种情况,将出现致命错误并终止。
// 因为代码无副作用,仅作诊断之用,因此无需在发布版本中运行。
checkCode(
if (!IsEverythingOK())
{
UE_LOG(LogUObjectGlobals, Fatal, TEXT("Something is wrong with %s!Terminating."), *GetFullName());
}
);
// 此列表中不应有圆圈,若有,程序将停转。但检查圆圈耗时较长,因此建议在调试版本中操作。
checkSlowf(!MyLinkedList.HasCycle(), TEXT("Found a cycle in the list!"));
//(遍历列表,在各个元素上运行一些代码。)
-------------------------------------------------- ------------------------------