青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 16,  comments - 34,  trackbacks - 0

題目有點繞口……

問題見: http://bbs2.chinaunix.net/viewthread.php?tid=1373280

 

問題描述

 

問題解答

 


 

問題分析

需要注意:
I. 宏是作文本替換
II. 替換的終止條件是:文件中不再含有宏

對第9行的:SET_NAME(1212)
1. 首先根據I和第5行,SET_NAME(1212) 會被替換成:CONNECTION(test,1212)
2. CONNECTION依然是一個宏,根據II,繼續替換
3. 根據I和第4行,CONNECTION(test,1212),被替換為 test1212
4. 所以第10行最終會被CPP替換成 "int test1212 = 1212;"

對第12行的:SET_NAME(VAR)
1. 首先根據I和第5行,SET_NAME(VAR)會被替換成:CONNECTION(test,VAR)
2. CONNECTIONVAR依然是一個宏,根據II,繼續替換
3. 根據I和第11行,CONNECTION(test,VAR)被替換為CONNECTION(test,326)
4. 再根據I和第4行,CONNECTION(test,326)被替換為test326
5. 所以第12行最終會被CPP替換成 "int test326 = 326;"

對第16行的:SET_NAME(VAR),同第12行,最終會被替換成 test86



為什么setname不行?
setname(var) 會被替換成 testvar,而后者不再含有宏,替換終止


 

常見應用

根據行號命名——為了取一些相互不沖突的名字,使用行號作為后綴
因為__LINE__也是一個,所以需要這種方法。

例1,Loki::ScopeGuard

Loki::ScopeGuard

 

Loki::ScopeGuard MACRO 示例


 1// Loki::ScopeGuard macro sample
 2// Loki::ScopeGuard : 范型、輕量的RAII技術 ,對資源管理與異常安全提供非常強大的支持
 3// 該處僅演示使用__LINE__作變量后綴名的方法, 暫不討論Loki::ScopeGuard
 4
 5#include <cassert>
 6#include <cstdio>
 7#include <stdexcept>
 8#include <string>
 9#include <loki::ScopeGuard>
10
11void CopyFile(const char* input_file,const char* output_file) /* throw(std::exception) */ {
12    using namescape std;
13
14    FILE* input = fopen(input_file,"r");
15    if (!input) throw runtime_error( string("can't open input file :"+ input_file);
16    LOKI_ON_BLOCK_EXIT(fclose,input);
17
18    FILE* output = fopen(output_file,"wb");
19    if (!output) throw runtime_error( string("can't open output file :"+ output);
20    LOKI_ON_BLOCK_EXIT(fclose,output);
21
22    enum { buf_size = 1212 };
23    char buf[buf_size];
24    size_t r = buf_size;
25
26    do {
27        r = fread(buf,1,buf_size,input);
28        if ( buf_size != fwrite(buf,1,buf_size,output)
29            throw runtime_error( string("write output file : "+ output + " occurs an error" );
30    }

31    while ( r == buf_size );
32
33    if ( !feof(input) {
34        assert( ferror(input) );
35        throw runtime_error( string("read input file : "+ input + " occurs an error");
36    }

37}

38
39
40int main() {
41    try 
44    catch (std::exception& e) 
47}

48


 代碼中16和20行,根據loki/ScopeGuard.h (658)中的定義,將被分別替換成:

::Loki::ScopeGuard scopeGuard16 = ::Loki::MakeGuard(fclose,input);
::Loki::ScopeGuard scopeGuard20 
= ::Loki::MakeGuard(fclose,output);

也就是定義2個名字以scopeGuard為前綴文件行號為后綴的“變量”(名字就不會重復)。
它們在退出作用域的時候會分別調用:fclose(input); fclose(output);
PS:ScopeGuard的強大還不僅僅體現在這里,以后會專門介紹。


例2.1,內嵌匯編或者使用goto時,需要一個不重復的跳轉標號。

make label



例2.2,做鍵盤模擬的時候,按照i8042的規則,每次寫入端口時,需要等待輸入緩沖為空。
所以需要實現一個 KBC_Wait4IBE (key board controller wait for input buffer empty)



但是又不想有函數調用消耗,所以打算用宏實現。
實驗1: 失敗的例子


#define KBC_WAIT4IBE()  \
KBC_WAIT4IBE_label:     \
_asm in AL,64h      \
_asm    TEST AL,10B \
_asm    JNZ KBC_WAIT4IBE_label


void KBC_KeyDown(byte scan) {
    KBC_WAIT4IBE(); // 等待輸入緩沖為空
    _outp(CMD_PORT,CMD_WRITE_OUTPUT_REG); // 準備寫入數據
    KBC_Wait4IBE(); // error C2045: 'KBC_WAIT4IBE_label' : label redefined
    // 標號重復
}


有一個辦法就是給標號加上行號作為后綴,那么在一個文件中也不會重復(使用 #line 除外……)。


btw:上面那個函數實現 KBC_Wait4IBE ,在VC8 release編譯下,會直接被inline,并且生成的代碼和KBC_WAIT4IBE完全相同……
所以,要信任編譯器的優化,不要無謂的犧牲可讀性~


重要補充! 上述解釋并不準確!!!
setname(var) 中的var同樣是一個宏,為什么不被替換?
SET_NAME(VAR)的第1次替換時,同樣VAR沒有被替換,為什么第2次替換就會被替換?

根據《代碼自動生成-宏帶來的奇技淫巧》:http://m.shnenglu.com/kevinlynx/archive/2008/03/19/44828.html
的說法,第2次替換時,涉及一個叫prescan的機制。
我平時對CPP研究不多,所以也沒弄明白這個機制。硬盤里專門講C的書也不多,我翻翻看有沒有詳細介紹的……

感興趣的讀者還可以參考: http://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Macros.html



 

再補充一點: 關于于宏的調試。
在MSVC下,可以給某個編譯單元xxx.c(cpp,cxx)加入"/P"(不含引號,P一定大寫)命令。
編譯該單元后,會在xxx.c的同目錄下生成xxx.i,即預處理的結果。
在GCC下,可以使用 gcc(g++) -E xxx.c(cpp,cxx) (必要時還需要 -i ),查看預處理結果。



再次補充

在《The C Programming Language》 2nd Edition中找到了解釋
附錄A.12.3 Macro Definition and Expansion p207。
以下只摘錄重點部分:
During collection(指第1次), arguments are not macro-expanded.
In both (指帶參數或者不帶參數)kinds of macro, the replacement token sequence is repeatedly rescanned for more defined identifiers.


沒能搜到ANSI C標準的文檔……

posted on 2009-02-18 23:59 OwnWaterloo 閱讀(3501) 評論(4)  編輯 收藏 引用

FeedBack:
# re: 使用宏作宏參數
2009-02-19 09:25 | 飄雪
好文,我原來對這個問題也想了很久  回復  更多評論
  
# re: 使用宏作宏參數
2009-02-19 09:52 | 路青飛
我可不可理解為,宏中宏!
哈哈!好文!贊一個!  回復  更多評論
  
# re: 使用宏作宏參數
2009-02-19 11:50 |
不錯,終于明白這個問題了!當初困擾我很久,還是沒有解決的問題!哈哈  回復  更多評論
  
# re: 使用宏作宏參數
2010-05-10 17:05 | PattersonGay
That is good that we are able to receive the <a href="http://lowest-rate-loans.com/topics/home-loans">home loans</a> and that opens new opportunities.   回復  更多評論
  
# re: 使用宏作宏參數
2010-08-08 14:31 | ringtone
Any human in the our world wants to stay original, but does not know the correct way to do it. But thousands of different people look for the ringtones download or just composer ringtones to be unique.   回復  更多評論
  
# re: 使用宏作宏參數
2012-07-02 09:25 | on line essays
To my mind, here only we receive the groundbreakingnewfangled brilliant data just about this good topic and that can be easygoing for men to buy term papers or buy an essay bestwritingservice.com from the professional custom essays writing firm.   回復  更多評論
  
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(8)

隨筆檔案(16)

鏈接

搜索

  •  

積分與排名

  • 積分 - 198759
  • 排名 - 134

最新隨筆

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美在线啊v| 欧美日韩一区二区三区| 久久在线视频在线| 欧美一区二区在线看| 亚洲一区二区三区视频播放| 亚洲一区二区三区视频| 午夜一区不卡| 久久综合久久美利坚合众国| 亚洲大片精品永久免费| 免费观看日韩| 亚洲人成小说网站色在线| 欧美一区二区视频免费观看| 一区二区精品| 午夜精品久久久久久久99樱桃 | 欧美电影免费观看高清| 欧美—级在线免费片| 国产精品乱码人人做人人爱| 国模套图日韩精品一区二区| 亚洲国产精品综合| 午夜精品福利视频| 男男成人高潮片免费网站| 日韩视频免费在线观看| 亚洲欧美日韩人成在线播放| 免费欧美日韩| 国产欧美视频一区二区三区| 亚洲精品久久久久久久久久久久久| 亚洲一区二区三区中文字幕在线| 久久久久久久999| 妖精视频成人观看www| 久久精品国产亚洲一区二区三区 | 这里只有精品在线播放| 欧美一区日韩一区| 亚洲欧美激情视频在线观看一区二区三区 | 麻豆视频一区二区| 亚洲欧洲综合另类在线| 香蕉成人久久| 亚洲国产一区二区三区a毛片 | 99亚洲一区二区| 久久视频在线视频| 国产精品中文字幕在线观看| 日韩性生活视频| 久热精品在线| 亚洲制服少妇| 欧美日韩一区三区四区| 亚洲日产国产精品| 免费在线观看成人av| 午夜性色一区二区三区免费视频| 欧美精品色综合| 91久久视频| 欧美高清视频一区| 久久精品视频免费播放| 国产真实乱子伦精品视频| 午夜精彩视频在线观看不卡| 99香蕉国产精品偷在线观看| 欧美精品久久久久久久| 亚洲欧洲精品成人久久奇米网| 久久综合狠狠综合久久综青草| 亚洲欧美日韩成人| 国产欧美日韩视频一区二区| 欧美亚洲日本一区| 亚洲欧美国产精品va在线观看| 国产精品久久久久影院色老大 | 日韩一级免费| 欧美日韩国产精品一区| 99国产精品久久久久久久| 亚洲国产欧洲综合997久久| 国产欧美日韩在线播放| 欧美三级电影网| 亚洲综合色网站| 亚洲图片欧美一区| 国产欧美日韩精品专区| 久久国产欧美| 久久久天天操| 亚洲区欧美区| 亚洲每日更新| 国产精品一区二区三区久久久 | 午夜欧美精品久久久久久久| 日韩视频在线观看国产| 欧美视频一区在线观看| 国产精品中文字幕欧美| 亚洲国产精品va| 亚洲区一区二| 国产精品一二三四| 久久视频精品在线| 欧美 日韩 国产在线| 亚洲精品一区二区网址| 亚洲精品中文字幕有码专区| 国产精品日本一区二区 | 亚洲国产视频直播| 亚洲美女91| 国产女优一区| 亚洲国产精品v| 国产精品香蕉在线观看| 鲁大师成人一区二区三区| 欧美成人精品1314www| 亚洲综合另类| 欧美电影电视剧在线观看| 欧美亚洲一区二区在线| 免费观看成人网| 久久激情视频久久| 欧美精品一区在线播放| 久久精品一区二区三区不卡| 欧美激情第1页| 国产亚洲欧美日韩精品| 亚洲福利视频网| 国产精品欧美日韩久久| 欧美韩日视频| 国产欧美一区二区精品性色| 亚洲国产成人在线播放| 国产欧美日韩免费| 99国产精品久久久久久久成人热| 激情欧美日韩一区| 亚洲一区二区三区免费视频| 亚洲茄子视频| 久久久久国产精品人| 先锋亚洲精品| 欧美日韩国产小视频| 欧美国产大片| 影音欧美亚洲| 久久成人18免费观看| 午夜精品久久久久久久久| 欧美精品免费视频| 欧美黄色免费网站| 尤物九九久久国产精品的分类| 亚洲图片欧美一区| 亚洲女人天堂成人av在线| 欧美激情一区二区三区| 欧美成人一区二区三区在线观看 | 亚洲综合三区| 欧美日韩八区| 亚洲欧洲在线视频| 亚洲人成艺术| 欧美成人国产| 亚洲国产成人精品久久| 亚洲国产欧美一区| 蜜桃精品久久久久久久免费影院| 免费看成人av| 亚洲国产高清视频| 久热精品视频在线观看| 欧美精品国产一区| 久久亚洲不卡| 国产精品视频网| 国产精品久久久久三级| 在线免费观看成人网| 久久久精品国产免费观看同学| 久久精品在线播放| 狠狠色综合网站久久久久久久| 久久se精品一区精品二区| 久久色中文字幕| 1024精品一区二区三区| 欧美va天堂在线| 亚洲免费电影在线观看| 亚洲综合成人婷婷小说| 国产精品一区免费视频| 久久精品视频导航| 亚洲国产黄色| 午夜精品久久久久久久白皮肤| 国产裸体写真av一区二区| 亚洲一区二区三区精品动漫| 欧美一区1区三区3区公司| 国内精品久久久久久久97牛牛| 久久亚洲图片| 亚洲区一区二| 久久国产精品99久久久久久老狼| 一区二区三区在线高清| 欧美激情久久久久久| 亚洲特色特黄| 久久在线精品| 一本综合精品| 国产一级揄自揄精品视频| 另类人畜视频在线| 在线视频亚洲| 蜜臀va亚洲va欧美va天堂| 夜夜躁日日躁狠狠久久88av| 国产色综合网| 欧美日韩国产一区二区三区地区| 亚洲欧美在线看| 亚洲区一区二| 米奇777超碰欧美日韩亚洲| 99这里只有久久精品视频| 国产日韩欧美二区| 欧美区高清在线| 亚洲欧美日韩国产成人| 亚洲人成在线观看| 久久久久这里只有精品| 一本色道久久综合亚洲精品婷婷 | 亚洲一区二区免费看| 免费日韩成人| 欧美亚洲一区二区在线| 99热精品在线观看| 狠狠干狠狠久久| 国产精品久久一卡二卡| 老司机午夜免费精品视频| 性色一区二区| 99视频超级精品| 亚洲激情社区| 欧美aⅴ99久久黑人专区| 亚洲男女自偷自拍图片另类| 亚洲看片免费| 亚洲精品国精品久久99热一|