一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

VC知識(shí)庫(kù):#define NDEBUG是what?

 黃南山 2017-06-21
主      題: #define NDEBUG是what?
作      者: wjyok_2005
回復(fù)次數(shù): 5
發(fā)表時(shí)間: 2007-1-26 8:39:13
正文內(nèi)容: 無

回復(fù)人: YangTze (得分:2)2007-1-26 8:41:20
就是說 有 NDEBUG 這么個(gè)符號(hào)定義存在


回復(fù)人: wjyok_20052007-1-26 8:43:05
他不是vc6提供的東西么?


回復(fù)人: leiallok (得分:4)2007-1-26 8:44:02
Re:#define NDEBUG是what?
按照字母序首先我們來看看<assert.h>,這個(gè)文件提供的接口功能很簡(jiǎn)單,但卻是我們極其常用的功能-斷言機(jī)制(如果條件為False,則輸出Diagnostics信息,然后Abort)。當(dāng)然在最終產(chǎn)品中使用斷言并不是一種好的方法,不過斷言是一種很有用的幫助我們調(diào)試程序的好工具。

我們一般在程序的調(diào)試版本中使用斷言機(jī)制,一般用來對(duì)Input進(jìn)行Validation,輸出一些Diagnostics信息。如:
assert((idx > 10) && (idx < 100));

<assert.h>中提供一個(gè)宏assert,這個(gè)宏的功能由另一個(gè)宏NDEBUG(標(biāo)志是否是DEBUG版本)決定。如果NDEBUG宏在你include <assert.h>時(shí)沒有被定義,這時(shí)斷言功能開啟;否則斷言功能關(guān)閉。如:

#define NDEBUG
#include <assert.h> /* 此時(shí)斷言功能關(guān)閉 */

你也大可不必在你的各個(gè)源文件中控制斷言功能的開關(guān),在編譯器選項(xiàng)中同樣可以定義NDEBUG宏,如gcc -DNDEBUG test.c,當(dāng)然對(duì)于大的project,這些是應(yīng)該放在Makefile中的,這樣的結(jié)果就相當(dāng)于在你所有#include <assert.h>的地方之前定義了NDEBUG宏,也就是說在每個(gè)編譯單元中,斷言功能都是關(guān)閉的。

assert宏看起來很簡(jiǎn)單,但是由于其是C標(biāo)準(zhǔn)庫(kù)提供的接口,所以在實(shí)現(xiàn)的時(shí)候需要考慮的更加細(xì)致和全面一些。從上面的敘述上來看assert.h文件的結(jié)構(gòu)應(yīng)該大致如下:
#undef assert
#ifdef NDEBUG
#define assert(test) ((void)0)
#else
#define assert(test) ...
#endif

我們可以很輕松的就拿出一個(gè)assert的實(shí)現(xiàn)版本:
/* NDEBUG not defined */
#define assert(test) if (!(test)) \
fprintf(stderr, "Assertion Failed: %s, file %s, line %d\n", \
#test, __FILE__, __LINE__); \

那么這個(gè)版本的實(shí)現(xiàn)可以接受不,答案是不能。原因有以下幾點(diǎn):
1) 這個(gè)實(shí)現(xiàn)中直接用到了stderr和fprintf,這兩個(gè)符號(hào)都是在<stdio.h>中聲明的,但是C標(biāo)準(zhǔn)庫(kù)頭文件基本上都是各自獨(dú)立的,在<assert.h>中是不會(huì)再包含其他頭文件的,那么這就要求使用assert的程序自己包含<stdio.h>,這顯然不符合一個(gè)C標(biāo)準(zhǔn)庫(kù)的基本要求;
2) assert宏應(yīng)該最終展開為一個(gè)void expression,因?yàn)橛脩艉芸赡茉谒麄兊某绦蛑袑懗鱿?assert(0 < x), x < y)這樣的代碼來,而在上面的實(shí)現(xiàn)版本中,顯然assert展開后不是一個(gè)void expression。

我們?cè)賮砜纯碢.J.Plauger的實(shí)現(xiàn)版本:
/* NDEBUG not defined */
void _Assert(char *);
#define _STR(x) _VAL(x)
#define _VAL(x) #x

#define assert(test) (test) ? (void)0 \
: _Assert(__FILE__ ":" _STR(__LINE__) " " #test)

/* in xassert.c */
#include <assert.h>
#include <stdio.h>

void _Assert(char *msg) {
fprintf(stderr, "%s -- assertion failed\n", msg);
abort();
}
  
分析一下這一版本的實(shí)現(xiàn),首先assert宏并沒有直接調(diào)用任何庫(kù)輸出函數(shù),而是調(diào)用了一個(gè)自己實(shí)現(xiàn)的函數(shù)_Assert,把向stderr輸出診斷信息的活都交給了_Assert。_STR和_VAL是兩個(gè)輔助宏,用來將__LINE__字符串化。這里比較難懂的地方就是_Assert(__FILE__ ":" _STR(__LINE__) " " #test)這一句,其實(shí)這個(gè)也很好理解??纯聪旅嬲Z(yǔ)句的執(zhí)行結(jié)果:
printf("%s\n", "Hello" " " "Tony!");
執(zhí)行上面語(yǔ)句你會(huì)看到Hello Tony!,這樣一來實(shí)際上_Assert(__FILE__ ":" _STR(__LINE__) " " #test)就可以被理解為:
_Assert("THE_FILENAME_STRING" ":" "THE_LINE_STRING" " " "THE_TEST_STRING")




回復(fù)人: believefym (得分:2)2007-1-26 8:44:31
Re:就是說 有 NDEBUG 這么個(gè)符號(hào)定義存在
同意,只是存在這么一個(gè)宏,但是這個(gè)具體的值是不重要的,就可以把它忽略

回復(fù)人: yqever (得分:2)2007-1-26 8:44:59
不是吧?

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    国产精品亚洲二区三区| 国产激情一区二区三区不卡| 色哟哟精品一区二区三区| 色无极东京热男人的天堂| 中文字幕有码视频熟女| 亚洲一区二区三区三区| 久久精品福利在线观看| 久久99精品日韩人妻| 亚洲高清中文字幕一区二三区 | 好东西一起分享老鸭窝| 国内外激情免费在线视频| 欧美成人久久久免费播放| 久久免费精品拍拍一区二区| 久久碰国产一区二区三区| 中文字幕无线码一区欧美| 国产免费一区二区三区不卡| 色婷婷激情五月天丁香| 欧美熟妇一区二区在线| 久久黄片免费播放大全| 精品欧美国产一二三区| 亚洲乱妇熟女爽的高潮片| 日韩在线一区中文字幕| 久久精品国产亚洲av久按摩| 真实偷拍一区二区免费视频| 欧美不卡高清一区二区三区| 国产又粗又长又大高潮视频| 永久福利盒子日韩日韩| 99久免费精品视频在线观| 国产精品国产亚洲看不卡| 亚洲夫妻性生活免费视频| 激情亚洲内射一区二区三区| 男女激情视频在线免费观看| 日本欧美一区二区三区在线播| 在线精品首页中文字幕亚洲| 东京热男人的天堂一二三区| 久久机热频这里只精品| 熟妇人妻av中文字幕老熟妇| 欧美日韩亚洲精品内裤| 99精品国产一区二区青青| 自拍偷拍一区二区三区| 亚洲精品福利视频你懂的|