java断言与断点_断言 - 游戏蛮牛 - Unreal中文翻译用户手册

本文详细介绍了UE4引擎中使用的断言宏,包括check、verify、checkf、verifyf等,以及它们在不同编译配置下的行为。此外,还提到了慢速断言宏checkSlow和确保宏ensure系列,这些工具用于在开发过程中检测代码的正确性和调试问题。
摘要由CSDN通过智能技术生成

断言

断言是一种工具,用于确认一段给定代码所依赖的假设。简单而言,它可确认指针不为 NULL;复杂而言,它可确认特定函数无法被重新进入。UE4 提供一系列宏,以执行这些类型的确认。它们为宏,以便在特定编译配置中进行译出(出于性能因素或因为最终版本中不需要它们)。在以下路径中可查看宏:

/UE4/Engine/Source/Runtime/Core/Public/Misc/AssertionMacros.h.

运行时断言宏有三种类型:停止执行、在调试版本中停止执行和不停止执行报告错误。第一种和第三种类型的编译取决于 DO_CHECK 定义。第二种类型的编译使用 DO_GUARD_SLOW 定义。如任意定义设为 0,宏将被禁用且不影响执行。

我们一起来看看断言宏的第一类。如断言不为 true,以下宏将全部停止执行。如在调试器中运行,断言将导致断点的出现,以便查看如何到达此点。

check(expression);

此宏执行表达式;如出现 false 的断言,将停止执行。在宏被编译到版本中后(DO_CHECK=1),才会执行表达式。这是 check() 宏的最简单形态。

范例:

check(Mesh != nullptr);

check(bWasInitialized && "Did you forget to call Init()?");

verify(expression);

启用 DO_CHECK 后,此宏的行为与 check() 完全相同。然而 DO_CHECK 被禁用后表达式仍然在执行。可使用它确认变量的指定符合假设。

范例:

verify((Mesh = GetRenderMesh()) != nullptr);

checkf(expression, ...);

checkf() 宏允许您将一个表达式断言为 true,并在调试时打印有帮助的额外信息。在编译行为方面,它和 check() 行为相同。

范例:

checkf(WasDestroyed, TEXT( "Failed to destroy Actor %s (%s)"), *Actor->GetClass()->GetName(), *Actor->GetActorLabel());

checkf( TCString::Strlen( Key ) >= KEYLENGTH( AES_KEYBITS ), TEXT( "AES_KEY needs to be at least %d characters" ), KEYLENGTH( AES_KEYBITS ) );

verifyf(expression, ...);

verify() 宏固定执行表达式,verifyf() 也是如此。和 checkf(); 一样,它通过额外的调试信息停止执行

范例:

verifyf(Module_libeay32, TEXT("Failed to load DLL %s"), *DLLToLoad);

checkCode(expression);

与通常的 check() 相比,该宏稍显复杂。该宏在执行一次的 do/while 循环中执行表达式。表达式被放置在标出其范围的 do/while 括号中。这在引擎中不常用,但如有需要也可使用。和一个标准 check() 宏相同,DO_CHECK 被禁用时此宏将编译出结果。不使用存在必需副作用的表达式,因为 DO_CHECK 被禁用时代码已移除。

范例:

checkCode( if( Object->HasAnyFlags( RF_PendingKill ) ) { UE_LOG(LogUObjectGlobals, Fatal, TEXT(“对象 %s 是被标记为 RF_PendingKill! 的根集的一部分”), *Object->GetFullName() ); } );

checkNoEntry();

此宏不接受表达式,用于标记从不执行的代码路径。

范例:

switch (MyEnum)

{

case MyEnumValue:

break;

default:

checkNoEntry();

break;

}

checkNoReentry();

checkNoReentry() 宏可防止调用重新进入一个给定函数。在只应被调用一次的函数上使用它,必须完成后方可再次被调用。

范例:

void NoReentry()

{

checkNoReentry();

}

checkNoRecursion();

执行和 checkNoReentry() 相同的检查,但使用能更清楚表达含义的命名。

范例:

int32 Recurse(int32 A, int32 B)

{

checkNoRecursion();

return Recurse(A - 1, B - 1);

}

unimplemented();

DO_CHECK 宏第一类中的最后一个宏用于标记在特定类上应被覆写或不应被调用的函数,因为此函数不包含实现。

范例:

class FNoImpl

{

virtual void DoStuff()

{

// 必须对此进行覆写

unimplemented();

}

};

启用 DO_GUARD_SLOW 后,断言宏的第二类才会执行。DO_GUARD_SLOW 通常只在调试版本中启用,但也可针对项目进行修改。它们的运行较为缓慢,在开发或发布版本中不需要进行许多无谓的检查。这些宏的执行与较快的宏并无差异。这些宏是 checkSlow()、checkfSlow() 和 verifySlow()。

范例:

checkSlow(List->HasCycle());

checkfSlow(Class->IsA(AActor::StaticClass()), TEXT("Class (%s) is wrong type"), Class->GetName());

verifySlow(LastValue == Current);

运行时断言的最终类不会停止执行,它用于创建一个调用堆栈报告,帮助追踪问题。这些宏中的表达式固定被执行,并可被放置在条件语句中。这些宏可通过 DO_CHECK 定义启用。

ensure(expression);

确认表达式,以及引导到此点调用堆栈的生成是否失败。

范例:

if (ensure( InObject != NULL ))

{

InObject->Modify();

}

ensureMsg(expression, message);

确认表达式并生成一个带额外信息的调用堆栈(作为报告的部分)。

范例:

ensureMsg(Node != nullptr, TEXT("Node is invalid"));

ensureMsgf(expression, message, ...);

确认表达式并包含带生成报告调用堆栈的更多信息。和 checkf() 或 verifyf() 相同,包括上下文信息有助于追踪问题。

范例:

if (ensureMsgf(!bModal, TEXT("Could not create dialog because modal is set to (%d)"), int32(bModal)))

{

...

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值