C++ assert implementation in assert.h

后端 未结 4 1659
灰色年华
灰色年华 2020-12-16 18:05
00001 /* assert.h
00002    Copyright (C) 2001, 2003 Free Software Foundation, Inc.
00003    Written by Stephane Carrez (stcarrez@nerim.fr)       
00004 
00005 This f         


        
4条回答
  •  离开以前
    2020-12-16 18:24

    Almost...

    Consider: assert( a == 0 ); This is expanded to

    (void)((a == 0) || (__assert (#a == 0, __FILE__, __LINE__),0))

    If you have the expression (x || y) - In this case both x and y evaluate as bools, so if 'a' evals to 0, the definition of || says to try the next bool in line, ie 'y'

    So - if your assertion is false, (__assert (#a == 0, __FILE__, __LINE__),0) gets evaluated, which means __assert() gets called.

    Why the (__assert(), 0) ?? __assert is a function defined as void __assert() - well ... most of the time. see http://www.opensource.apple.com/source/Libc/Libc-825.26/include/assert.h for one set of assert() macros - note that all of them end up calling a function ...

    The comma operator lets you do two things in the same statement, ie i++, j++ - but remember an expression has to evaluate to some value - in this case to the "0" - so the entire statement evaluates to (void)(0 || 0) which is a valid expression. As a side effect, your expression is evaluated and possibly a function gets called.

    Note in (void)(0 || 0) the first 0 is from your failed assertion. This may be created at compile time if your assertion evaluates to something the compiler can create as a constant, or an expression that gets evaluated, ie (void)((a == 0) || 0)

    note the comma ",0" is for really pedantic compilers - I usually don't see it. But the (a || __assert()) is very common. You could write the macro as

    #define assert( x ) { if( ! (x)) __assert(.....); }
    

提交回复
热议问题