源码摘抄
#ifdef UNIV_DEBUG
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) ut_a(EXPR)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) do {EXPR;} while (0)
#else
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR)
#endif
上述代码涉及到define 宏定义用法 如下:
define function(x) do{} while()
我们常见的一种是 define N 100 定义常量 。
看上面用法:
#define ut_d(EXPR) do {EXPR;} while (0)
while (0) 为false,只执行一次 do 。如果while里值大于0,那么条件为真,将一直执行 do ,除非在里面添加break 跳出。
参考这篇文章do{...}while(0)的意义和用法 看到这篇文章真是茅塞顿开。
再回到源码。 ifdef univ_DEBUG 如果执行了debug 将执行下面的 else 执行下面的 endif 。 ifdef ..... else ...... endif 结构
下面摘抄一段 mysql 源码中调用的 lock0lock.c :: lock_clust_rec_cons_read_sees()函数
/*********************************************************************//**
Checks that a record is seen in a consistent read.
@return TRUE if sees, or FALSE if an earlier version of the record
should be retrieved */
UNIV_INTERN
ibool
lock_clust_rec_cons_read_sees(
/*==========================*/
const rec_t* rec, /*!< in: user record which should be read or
passed over by a read cursor */
dict_index_t* index, /*!< in: clustered index */
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
read_view_t* view) /*!< in: consistent read view */
{
trx_id_t trx_id;
ut_ad(dict_index_is_clust(index)); // 只在debug模式下才会执行一次
ut_ad(page_rec_is_user_rec(rec)); // 只在debug模式下才会执行一次
ut_ad(rec_offs_validate(rec, index, offsets)); //只在debug模式下才会执行一次
/* NOTE that we call this function while holding the search
system latch. To obey the latching order we must NOT reserve the
kernel mutex here! */
trx_id = row_get_rec_trx_id(rec, index, offsets);
return(read_view_sees_trx_id(view, trx_id));
}
mysql好多ut_ad()这种断言调用,这次终于搞明白了。