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)) 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. thanks in advance, Mariano |
Hi Mariano, On Mon, Dec 20, 2010 at 1:22 AM, Mariano Martinez Peck <[hidden email]> wrote:
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.
that's right. HTH Eliot
|
Thanks Eliot. This has been very helpful. A problem I have debugging this asserts in Cog is that when an assert fails, it is not easy to discover why. So....I need to change the code, and ask an if, see if it fails, and if true, print the results. So, for example, if I have: self assert: newMethod ... mcType = CMFree then I need to add before that an if like this: (expression) ifFalse: [ "print the actual results to understand" ]. ->> (newMethod ... mcType = CMFree) ifFalse: [ self print: 'method type: '; self printNum: newMethod..mcType..]. do you understand? Now I was from my complete ignorance...if it could be possible to add a assert:equals: just the same as in TestCase: assert: expected equals: actual ^ self assert: (expected = actual) description: (self comparingStringBetween: expected and: actual) So then in the assert I can do: self assert: newMethod ... mcType queals: CMFree so after...in C, the message can be something like: received: "what newMethod ... mcType answers" but expected: CMFree. Do you think this is doable? thanks again in advance Mariano On Mon, Dec 20, 2010 at 7:53 PM, Eliot Miranda <[hidden email]> wrote:
|
when I see an assert fail I move to the Debug vm, set a breakpoint in warning and run my reproducible test case. It therefore breaks at the first assert fail and I can diagnose in the debugger. HTH
Eliot
On Tue, Dec 21, 2010 at 3:09 PM, Mariano Martinez Peck <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |