Wait! - this is not as silly a question as it sounds. The title is simply succinct.
I have some debugging code to verify the correctness of a data structure and some assertions checking this correctness, which I only want enabled in the Debug build:
{$ifdef DEBUG}
function Sorted : Boolean;
function LinearSearchByValue(const T : TType) : NativeInt;
{$endif}
and later in a method:
assert(Sorted);
for example.
In my debug build with assertions enabled, all is fine. However, in my Release build with assertions disabled, the line assert(Sorted); causes a compiler error E2003 Undeclared identifier: 'Sorted'. It's quite right, the identifier isn't declared, but assertions are also turned off and should not be being evaluated or have any code generated. (Trying to trick assert by declaring the method but having no implementation causes the normal error 'Unsatisfied forward or external declaration'. It is clearly looking for the method body as well.)
This is leading to some messy code where methods that should not exist in a Release build at all have to be declared and have a body, in order to compile asserts, which are turned off.
How do I declare methods that exist only in a debug build, and use those in assertions which should also only exist in the debug build, in Delphi 2010?
Further info:
I tried wrapping the method declarations with
{$ifopt C+}, which checks if assertions are switched on. The calls toassertstill failed with 'undeclared identifier'.Compiler options are definitely that assertions are turned off. (I checked :))
I have tried wrapping calls to
assertthat use these methods with{$ifdef DEBUG}. However, this is messy and should not be required. At one point it made me worried that assertions are being compiled even in Release builds, and for performance reasons I don't want them at all. (This is not happening - assert code is not generated.)My current strategy is to declare these methods all the time, but in a Release build ifdef the method body out and fill it with a dummy Result. The aim here is to all assertions to compile, but have as little overhead for the methods as possible, and their return value (should they have turned out to be actually called in a release build) to be clearly wrong.
Is there any equivalent to C/C++-style macros in Delphi, where an
ASSERT(x)macro would simply be defined as nothing in a release build, causing the compiler to neither see nor care about the statement inside the assertion? This is one of the few clean ways (IMO) to use macros in C++.
So while asserts are not being generated, they are compiled. This loops back to my question: How do I best mix debug-only methods and assertions, and release builds?
raise EAssertionFailedsince you should never get there. In fact I have a utility function namedRaiseAssertionFailedto do just that. - David HeffernanAssertcompiler magic has unique properties not available otherwise and is right tool for checking always-true conditions. - OnTheFlyAssertto get it. - Rob KennedyRaiseAssertionFailedin there. And of course it never executes. Apart from when I make a mistake. And then I find out about it. Which is what I want. - David Heffernan