Vorige Mail
Nächste Mail
Unformatiert/Volle Header
Übersicht 10 Tage
Betreff
Datum
Thread
Autor
Von: Gale Paeper
Betreff: Assertions - was Re: Code access to source name and line
Datum: 26.6.2003, 00:34:55
Peter N Lewis wrote:
> >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.
Although it wouldn't be backward compatible with CW Pascal, you might
want to look into using GPC's support for Extended Pascal's module
multiple interface exports and export renaming. For example:
module MyLists;
export MyLists = (AppendToList);
MyListsDebug = (AppendToListDebug => AppendToList);
{insert const and type declarations needed for interface declarations}
procedure AppendToList( var list: ListType; item: ItemType );
procedure AppendToListDebug( var list: ListType; item: ItemType );
end; {module heading}
function ValidList( protected var list: ListType): boolean;
{insert list validation implementation code block}
procedure AppendToList( var list: ListType; item: ItemType );
{insert procedure's implementation code block}
procedure AppendToListDebug( var list: ListType; item: ItemType );
begin
{pre-condition asserts go here}
Assert( ValidList( list ) );
AppendToList( var list: ListType; item: ItemType );
{post-condition asserts go here}
end;
end. {module block}
Then in code using the MyLists module, use conditional compilation
directives to select the debugging interface or the non-debugging
interface. For example:
procedure DoSomethingWithLists;
{$ifc not do_debug}
import MyLists;
{$elsec}
import MyListsDebug in 'MyLists.pas';
{$endc}
{insert other needed declarations}
begin
{...}
{With do_debug = true, this ends up calling AppendToListDebug with the
pre- and post-conditions
assertion checks. Otherwise, it calls AppendToList which doesn't have
the assertion overhead.}
AppendToList(theList,anItem);
end;
Then as long as you practice a discipline of side-effect free
pre-condition and post-condition asserts, the effects of
debugging/non-debugging versions will be transparent; will retain
modularity; and will avoid the debugging code overhead in non-debug
production code. If you're using a smart linker, the debugging code
routines should also be dead stripped from the production executeable
since the debugging related routines are never called from production code.
Vorige Mail
Nächste Mail
Unformatiert/Volle Header
Übersicht 10 Tage
Betreff
Datum
Thread
Autor
Hinweis: Diese Seite enthält Informationen, die nicht vom Betreiber dieser Website, sondern von den Autoren der archivierten Mails stammen. Der Betreiber dieser Website ist nicht für den Inhalt dieser Informationen verantwortlich. Die weitere Verwendung dieser Informationen bedarf des Einverständnisses des jeweiligen Autors.
Sofern WWW-Adressen (URLs) in den archivierten Mails als Hyperlinks hervorgehoben werden, so geschieht dies ausschließlich zur Annehmlichkeit für den Leser. Der Inhalt der auf diese Weise angelinkten Webseiten spiegelt nicht notwendigerweise die Meinung des Betreibers dieser Webseite oder der Autoren der archivierten Mails wider. Der Betreiber dieser Webseite ist nicht für den Inhalt solcher Webseiten verantwortlich. Diese Seiten sind ausdrücklich nicht als Teil des Inhalts dieser Seite zu betrachten, sondern lediglich als Referenzen.
Diese Seite wurde erzeugt von Crystal 0.999 (Linux 2.4.27/i686).