But I don't really understand the difference you make between turned off and compiled out. If assertions are turned off, no code is generated for them, unless they have side-effects, i.e. cases such as:
{ Returns True on success, False on failure. } function Foo (a: Integer): Boolean; [...]
Assert (Foo (42));
With assertions turned off, this is equivalent to:
Dummy := Foo (42);
(where Dummy is an otherwise unused Boolean variable).
That's the point. My assertions tend to be things like:
Assert( ValidDataStructure( x ) );
ValidDataStructure might be a very expensive call, it might parse through the entire data structure looking for holes in it.
This behaviour may be debatable. I think it would be more risky to discard side-effects as well (especially if most testing is done with assertions turned on).
But I'm not sure if that's actually what you're referring to.
Absolutely, it is definitely a case of tradeoffs. You have to be disciplined about your use of Asserts to ensure you never use any code in them that is required to be executed. It's all too easy to write things like:
Assert( OpenFile( f, name ) = noErr );
As I said, I fully understand why they are done the way they are done. However for me, the tradeoff with that is that it restricts the cases I would be willing to use Assert for. No one would want to write code like:
procedure AppendToList( var list: ListType; item: ItemType ); begin Assert( ValidList( list ) ); ...
if they new that in the production code their O(1) AppendToList function would actually be O(n) or worse.
It's a trade off of safety (in executing potentially side effect riddled code) with safety (in writing reliable well tested programs).
GPC also makes this more challenging because you can't define a macro in any given unit for asserting the validity of data structures because that macro is not propagated into the using units. For example, in the interface my hypothetical Lists unit above, I would add something like:
{$ifc not do_debug} {$definec AssertValidList( list )} {$elsec} {$definec AssertValidList( list ) AssertValidListCode( list, SrcFile, SrcLine )} {$endc}
{$ifc do_debug} procedure AssertValidListCode( list: ListType; source: String; line: Integer ); {$endc}
but that does not work in GPC. My solution has been to use a prefix file and copy all such macro definitions to the prefix file. This is less than ideal since it breaks the modularity. Perhaps someone has a better solution for me, but it's the best I can come up with so far.
BTW, I really really strongly recommend that all programs go and read Writing Solid Code.
Enjoy, Peter.