Download

How to use assert in a debug build

HI I am trying to integrated a this party library to unreal
I set my configuration to win64->Debug Editor
but it seems some how that assert at compiled out regales of any configuration, an I do not see a Unreal version

something like this should trigger an assert,



#include <assert.h> 
void AssertTest()
{
	int test = 0;
	assert(test);
}

but the code I compile out, the code translate to this.


#include <assert.h> 
void AssertTest()
{
00007FFE0AC39E00  push        rdi  
00007FFE0AC39E02  sub         rsp,10h  
00007FFE0AC39E06  mov         rdi,rsp  
00007FFE0AC39E09  mov         ecx,4  
00007FFE0AC39E0E  mov         eax,0CCCCCCCCh  
00007FFE0AC39E13  rep stos    dword ptr [rdi]  
	int test = 0;
00007FFE0AC39E15  mov         dword ptr [rsp],0  
	assert(test);
}
00007FFE0AC39E1C  add         rsp,10h  
00007FFE0AC39E20  pop         rdi  
00007FFE0AC39E21  ret  

How can a developer use runtime assert to in code?

Take a look in AssertionMacros.h, I see Epic using the check(expr) macro in place of assert.

check, checkSlow, and ensure are the three mechanisms we typically use:

  • check() is a runtime assert that is compiled out in shipping and test builds (unless USE_CHECKS_IN_SHIPPING is 1).
  • checkSlow() behaves like a check() in debug and is compiled out otherwise (for safety checks that are good but rare / too slow to use in normal builds)
  • ensure() is for validating conditions that can still be handled even if they fail. It evaluates the expression and traps if the debugger is attached when it fails, but the code will keep executing afterwards. The expression itself is never compiled out (so you can write things like if (ensure(Foo != null)) { do stuff with Foo; }).

Cheers,
Michael Noland

RE: Third-party library. The assert() is probably gated based on the value of NDEBUG when the header is included. Even in a debug engine/editor build, we normally link against the Release version of the CRT for a speed boost:



case UnrealTargetConfiguration.Debug:
	CompileConfiguration = CPPTargetConfiguration.Debug;
	if (BuildConfiguration.bDebugBuildsActuallyUseDebugCRT)
	{
		InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_DEBUG=1"); // the engine doesn't use this, but lots of 3rd party stuff does
	}
	else
	{
		InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("NDEBUG=1"); // the engine doesn't use this, but lots of 3rd party stuff does
	}
	InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("UE_BUILD_DEBUG=1");
	break;


You can set bDebugBuildsActuallyUseDebugCRT in your BuildConfiguration.xml and do a rebuild if you really need to link against the debug CRT.

Cheers,
Michael Noland

But check doesn’t act like assert if you’re using PIE and have a debugger attached. You can’t ignore it and continue on. It acts much more like a fatal error and stops execution. There isn’t an option to stop PIE and fix the code, compile, and then PIE again. That is what we need from an assert.

Are there any other options that would provide this? Debug break on failed validation but can continue running and let what happens happen.

ensure() is a non-fatal exception. It traps when the debugger is attached but you can continue on past it.

[Note: The body of ensure() is evaluated even in shipping, so you might want to wrap it inside of a #if DO_CHECK #endif when using it in this manner]

Cheers,
Michael Noland

So in UE there is no option to have asserts if debugger is not attached ? I would like to see asserts in no editor mode. Where I can have buttons like : Ignore once, Ignore always and if I will have attached debugger then I will see break button. But obviously you are not supporting proper asserts :frowning:
Also have asserts in release version is very useful but not asserts which terminate the game. Asserts which allow you to what I said above.
Asserts with callstack and option to add a text why I triggered assert.