[Vm-dev] [Cog] Trying to understand #assert:

Eliot Miranda eliot.miranda at gmail.com
Mon Dec 20 18:53:05 UTC 2010


Hi Mariano,

On Mon, Dec 20, 2010 at 1:22 AM, Mariano Martinez Peck <
marianopeck at gmail.com> wrote:

>
> Hi Eliot. I noticed that in the Cog VM there are a lot of asserts in the
> code. I am trying to understand them but I have a couple of questions:
>
> - What happens with the code execution when an assert fails?  it stops the
> execution?  it continues? it raises an error?  I tried to follow to the
> definition of assert() but I only came to this:
> # define assert(expr)  ((expr)||(warning(#expr " "
> __stringifyNum(__LINE__)),0))
>

There are a few defines for asserts (in platforms/Cross/vm/sqAssert.h);
here's the entire file:

/*
 * An informative assert definition that prints expression and line number.
 *
 * assert's expression is evaluated only if NDEBUG is not defined and
printed
 * along with its the line number if it is false.
 *
 * asserta's expression is always evaluated but only printed if it is false
and
 * NDEBUG is not defined. (asserta => assert always)
 *
 * assertf's message is printed along with its line number if NDEBUG is not
 * defined. (assertfd => assert fail)
 */

extern void warning(char *);

#ifdef NDEBUG /* compatible with Mac OS X (FreeBSD) /usr/include/assert.h */
# undef assert
# define assert(expr) 0 /* hack disabling of asserts.  Better in makefile?
*/
# define asserta(expr) (expr)
# define assertf(msg) 0
# define PRODUCTION 1
#elif 1
# undef assert
# define __stringify(foo) #foo
# define __stringifyNum(n) __stringify(n)
# define assert(expr)  ((expr)||(warning(#expr " "
__stringifyNum(__LINE__)),0))
# define asserta(expr) ((expr)||(warning(#expr " "
__stringifyNum(__LINE__)),0))
# define assertf(msg)  (warning(#msg " " __stringifyNum(__LINE__)),0)
# define PRODUCTION 0
#endif

#define halt() warning("halt")

 So there are three assert functions, assert, asserta and assertf.  These
all print warnings if enabled; they do /not/ terminate execution - in the
VW/HPS experience getting asserts right can be hard so having them produce
warnings is more convenient than having them terminate execution.

Asserts are optional checks.  They are not present in the production VM
(since evaluating asserts may cost performance).  You'll see in the Cog VM I
build three VMs, the production one without asserts, the Assert VM with
asserts enabled and with moderate optimization, good for smoke testing, and
the Debug VM with asserts enabled but no optimization, good for debugging.

If enabled, assert prints a warning with the expression that failed, and the
line number

asserta like assert prints a warning if its expression is false, but its
expression is /always/ evaluated.  So if you disable asserts its expression
is still evaluated.  Hence
# define asserta(expr) (expr)
So if you have an expression that is being evaluated for effect but you
still want to check, use asserta.

assertf, if enabled, always prints a warning, so you use it when control
reaches a point it shouldn't, e.g. the end of a chain of if-the-elses.


> So....after time, I understood that when I compile in "development" and I
> run with GDB, and I have something printed in the console like:
>
> (primitiveIndexOf(GIV(newMethod))) != 0 8913
>
> this means that in the line 8913 the assert has failed?  so, do I
> understand correct?   when an assert fails, the code continues to execute,
> but it just prints the expresion + number of line in the console?
> if it doesn't fail, it doesn't print.
>

that's right.

HTH
Eliot


>
> thanks in advance,
>
> Mariano
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20101220/71afe060/attachment.htm


More information about the Vm-dev mailing list