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

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 閱讀(3507) 評論(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.   回復  更多評論
  
<2009年2月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
1234567

常用鏈接

留言簿(8)

隨筆檔案(16)

鏈接

搜索

  •  

積分與排名

  • 積分 - 198798
  • 排名 - 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>
            欧美一级播放| 国产欧美日韩在线视频| 欧美国产一区在线| 欧美福利小视频| 亚洲激情在线激情| 亚洲视频一区二区| 一本久久综合亚洲鲁鲁五月天| 国产乱人伦精品一区二区| 欧美高清在线一区| 国产专区综合网| 一区二区不卡在线视频 午夜欧美不卡'| 国产一区二区三区在线观看网站| 亚洲国产精品热久久| 国产美女精品一区二区三区 | 在线一区欧美| 亚洲高清免费在线| 久久精品一本| 久久夜色撩人精品| 在线不卡免费欧美| 久久精品国产一区二区电影| 欧美在线3区| 国产一区二区中文| 性欧美1819性猛交| 亚洲电影激情视频网站| 1024精品一区二区三区| 欧美.www| 亚洲一区二区日本| 久久一区二区三区超碰国产精品| 国内精品久久久久久久果冻传媒 | 久久亚洲精品视频| 亚洲第一区在线观看| 一区二区高清在线| 亚洲小说春色综合另类电影| 欧美一区二区大片| 亚洲国产第一| 亚洲韩国一区二区三区| 欧美伊久线香蕉线新在线| 国产美女精品免费电影| 免费日韩av电影| 99国产精品私拍| 欧美福利电影在线观看| 亚洲欧美日韩国产中文| 亚洲日韩欧美视频一区| 欧美日韩专区| 久久综合中文字幕| 欧美一区二区三区的| 久久蜜桃av一区精品变态类天堂| 一区二区欧美激情| 欧美激情无毛| 一本色道久久综合亚洲91 | 一本到12不卡视频在线dvd| 欧美伊人久久| 小嫩嫩精品导航| 国产精品一区二区男女羞羞无遮挡 | 国产精品亚洲成人| 老司机aⅴ在线精品导航| 亚洲国产精品999| 久久精品久久综合| 亚洲国产精品女人久久久| 久久久伊人欧美| 久久动漫亚洲| 影音先锋久久精品| 午夜精品美女久久久久av福利| 午夜久久久久久| 久久国产天堂福利天堂| 久久久久久亚洲精品中文字幕| 西西裸体人体做爰大胆久久久| 午夜精品电影| 久久女同互慰一区二区三区| 久久久www成人免费精品| 免费成人性网站| 99国产精品视频免费观看| 亚洲一区精品电影| 欧美在现视频| 欧美另类亚洲| 国产精品一区二区久激情瑜伽| 国产欧美日韩视频在线观看| 黄色成人av| 国产精品99久久久久久人 | 久久在线免费视频| 欧美日本高清| 国产日韩一区欧美| 一区二区精品国产| 久久亚洲风情| 亚洲欧美日本伦理| 欧美韩日精品| 久久久www| 一区二区日韩精品| 久久夜色精品国产亚洲aⅴ| 激情五月***国产精品| 香蕉亚洲视频| 亚洲第一精品福利| 久久精品国产综合精品| 欧美日韩一区二区三区四区在线观看| 欧美中文日韩| 国产偷自视频区视频一区二区| 亚洲午夜av电影| 欧美在线网站| 国内自拍一区| 男男成人高潮片免费网站| 久久午夜精品一区二区| 狠狠狠色丁香婷婷综合激情| 性做久久久久久免费观看欧美| 先锋a资源在线看亚洲| 久久久国产精品亚洲一区| 久久久久国产一区二区三区| 欧美jizz19性欧美| 国语精品一区| 欧美日韩在线免费观看| 午夜精品久久久久久久蜜桃app | 亚洲一区二区在| 国产欧美在线播放| 美女精品在线| 欧美日韩中文字幕精品| 一区二区三区欧美在线| 中文网丁香综合网| 欧美一区二区三区在线观看视频| 国产精品婷婷午夜在线观看| 亚洲国产高潮在线观看| 午夜精品视频在线观看| 亚洲国产精品一区| 国产欧美短视频| 欧美日韩国产在线播放| 久久人人爽人人爽爽久久| 国产一区亚洲一区| 欧美国产日韩一区二区| 亚洲女性喷水在线观看一区| 美女诱惑黄网站一区| 国产精品一二一区| 亚洲小说春色综合另类电影| 麻豆国产va免费精品高清在线| 欧美一级视频免费在线观看| 欧美福利网址| 最新日韩欧美| 亚洲激情另类| 欧美视频一区| 亚洲欧美国产精品va在线观看| 999在线观看精品免费不卡网站| 免费成人网www| 久久久天天操| 国语自产精品视频在线看抢先版结局| 亚洲一区欧美一区| 久久国产一区| 亚洲国产精品电影| 亚洲一区免费观看| 乱码第一页成人| 99精品视频网| 国产麻豆综合| 久久天堂精品| 日韩亚洲一区在线播放| 欧美www在线| 亚洲破处大片| 亚洲视频1区| 欧美91精品| 国产日本精品| 国产伪娘ts一区| 国产亚洲视频在线观看| 国产亚洲一区精品| 亚洲国产片色| 香蕉乱码成人久久天堂爱免费 | 久热成人在线视频| 久久久人成影片一区二区三区| 久久狠狠亚洲综合| 欧美成人国产| 亚洲精品日韩久久| 国产精品入口尤物| 久久人人爽人人爽爽久久| 日韩视频一区二区三区在线播放 | 国产精品裸体一区二区三区| 欧美一区=区| 亚洲免费观看在线视频| 国产欧美精品日韩精品| 亚洲福利一区| 久久精品视频va| 国产精品国码视频| 欧美金8天国| 久久精品中文字幕一区| 亚洲三级性片| a91a精品视频在线观看| 麻豆乱码国产一区二区三区| 国内精品视频在线播放| 欧美紧缚bdsm在线视频| 久久午夜影视| 欧美福利在线观看| 模特精品在线| 久久aⅴ国产紧身牛仔裤| 亚洲深夜激情| 亚洲综合久久久久| 99国产精品国产精品久久| 精品88久久久久88久久久| 国产日韩在线看| 巨乳诱惑日韩免费av| 久久精品1区| 欧美精品导航| 国产精品日韩欧美综合 | 久久中文精品| 欧美区国产区| 欧美日韩一本到| 国产香蕉97碰碰久久人人| 国产一区二区日韩精品|