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

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://www.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 閱讀(3567) 評論(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.   回復  更多評論
  

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2025年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用鏈接

留言簿(8)

隨筆檔案(16)

鏈接

搜索

  •  

積分與排名

  • 積分 - 199275
  • 排名 - 135

最新隨筆

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久精品国产欧美激情| 久久精品亚洲乱码伦伦中文| 欧美成人精品| 久久国产加勒比精品无码| 99精品福利视频| 国产精品成人观看视频免费| 亚洲天堂视频在线观看| 亚洲综合视频1区| 国产亚洲欧美日韩精品| 久久久久久久久久久久久久一区 | 在线日韩中文| 一区二区三区免费看| 99ri日韩精品视频| 国产精品日韩精品欧美精品| 久久av红桃一区二区小说| 久久激情网站| 亚洲免费观看高清在线观看| 国产精品99久久久久久久女警| 国产精品久久久久久久久婷婷| 欧美在线国产精品| 美女网站在线免费欧美精品| av成人激情| 久久国产精品久久久久久| 亚洲黄网站黄| 免费观看欧美在线视频的网站| 美女视频网站黄色亚洲| 亚洲一区在线观看视频| 久久成人精品一区二区三区| 日韩午夜精品| 欧美亚洲色图校园春色| 夜夜嗨av一区二区三区中文字幕| 亚洲在线观看| 亚洲狼人综合| 久久成人免费网| 亚洲免费在线播放| 欧美a级片网| 久久深夜福利| 国产精品卡一卡二| 最新国产精品拍自在线播放| 久久久欧美一区二区| 中文日韩欧美| 另类图片综合电影| 久久精品视频播放| 欧美日韩视频在线| 亚洲黄色一区二区三区| 加勒比av一区二区| 模特精品在线| 国产欧美综合一区二区三区| 99国内精品久久| 亚洲精品小视频| 免费不卡中文字幕视频| 欧美专区18| 国产精品毛片在线看| 亚洲精选中文字幕| 亚洲国产精品成人综合色在线婷婷| 美腿丝袜亚洲色图| 国产欧美精品一区| 在线综合+亚洲+欧美中文字幕| 亚洲精品中文字幕在线观看| 蜜臀91精品一区二区三区| 久久精品国产69国产精品亚洲| 欧美色大人视频| 最新日韩中文字幕| 亚洲剧情一区二区| 免费的成人av| 欧美激情视频在线播放| 亚洲第一主播视频| 久久夜色精品国产欧美乱| 久久午夜av| 欲色影视综合吧| 久久精品一区蜜桃臀影院 | 亚洲欧洲日韩在线| 久色婷婷小香蕉久久| 久久综合久久久久88| 国产一区三区三区| 欧美主播一区二区三区美女 久久精品人 | 欧美在线观看www| 久久视频国产精品免费视频在线 | 免费观看成人鲁鲁鲁鲁鲁视频| 麻豆精品精品国产自在97香蕉| 国内精品一区二区| 久久天堂国产精品| 亚洲国产精品毛片| 亚洲天堂激情| 国产性色一区二区| 久久久综合网| 亚洲乱码一区二区| 亚洲一区欧美一区| 黄色一区二区三区四区| 麻豆精品一区二区av白丝在线| 亚洲黄一区二区三区| 亚洲视频专区在线| 国产午夜精品麻豆| 欧美黄色免费| 亚洲视频导航| 老司机久久99久久精品播放免费| 亚洲高清久久久| 欧美三区在线视频| 久久国内精品自在自线400部| 欧美激情精品久久久久久| 一本色道久久综合| 国产偷国产偷精品高清尤物| 牛夜精品久久久久久久99黑人| 亚洲毛片在线看| 久久精品国产免费看久久精品| 亚洲国产日韩一区| 国产精品亚洲视频| 女女同性女同一区二区三区91| 一区二区电影免费观看| 老巨人导航500精品| 在线视频你懂得一区| 国内精品久久久久伊人av| 欧美日韩国产色综合一二三四| 欧美伊人久久久久久久久影院 | 亚洲人成人99网站| 久久精品视频va| 国产精品99久久久久久久久久久久| 国产视频精品va久久久久久| 欧美精品日韩精品| 久久久免费精品视频| 亚洲图片在线观看| 亚洲人久久久| 免费看亚洲片| 久久精品视频va| 亚洲欧美视频在线| 日韩亚洲欧美一区二区三区| 国产一区清纯| 国产亚洲a∨片在线观看| 欧美视频二区| 欧美人成网站| 欧美成人网在线| 欧美超级免费视 在线| 久久精品一区| 久久久国产91| 久久精品二区三区| 午夜久久tv| 亚洲欧美日韩专区| 亚洲一二三四区| 亚洲一级在线观看| 国产精品99久久久久久久久久久久| 亚洲人体大胆视频| 亚洲人精品午夜在线观看| 亚洲国产电影| 欧美激情一区二区三区 | 欧美主播一区二区三区| 亚洲欧美中文日韩v在线观看| 日韩写真在线| 亚洲一二三级电影| 一区二区三区国产| 亚洲天堂男人| 午夜精品久久久久久久99热浪潮| 亚洲色图综合久久| 亚洲少妇一区| 欧美一区二区网站| 久久三级福利| 欧美成人dvd在线视频| 欧美激情成人在线| 日韩网站免费观看| 亚洲香蕉成视频在线观看| 亚洲主播在线播放| 欧美在线日韩精品| 久久综合99re88久久爱| 欧美成人精品不卡视频在线观看| 男人插女人欧美| 欧美色网一区二区| 国产欧美一区二区白浆黑人| 国产一区二区在线观看免费| 在线观看日韩专区| 99国产精品久久久久久久成人热| 亚洲精品日韩在线| 亚洲免费在线视频| 麻豆精品精华液| 亚洲精品看片| 性欧美videos另类喷潮| 葵司免费一区二区三区四区五区| 欧美激情一区二区三区在线| 国产精品久久久久久久久| 国产婷婷97碰碰久久人人蜜臀| 亚洲电影第三页| 亚洲一区日韩在线| 麻豆精品一区二区综合av | 欧美大片专区| 99这里有精品| 久久人人九九| 国产精品久久久久久影视| 激情文学一区| 亚洲伊人网站| 亚洲国产婷婷综合在线精品| 中文在线资源观看网站视频免费不卡 | 亚洲激情在线播放| 亚洲欧美另类久久久精品2019| 美日韩精品视频免费看| 在线亚洲欧美视频| 欧美99在线视频观看| 国产乱理伦片在线观看夜一区| 最新日韩av| 久久精品国产综合精品| 亚洲免费观看高清在线观看| 久久亚洲私人国产精品va媚药| 国产精品视频免费在线观看|