stringification of macro values

引言

? ? ? ?學習redis源碼的過程中看到zmallo.h文件中有如下的宏定義:



? ? ? ?聯(lián)想到項目中也使用了這個技巧攒暇,當時使用這個技巧的原因在于形用,項目中定義了一個宏#define MARCS xxx,如果直接使用田度,還有一個宏為#define SPS_PRINT(a) #a。如果不在SPS_PRINT宏外側封裝另外一層宏乎莉,那么直接調用SPS_PRINT(MARCS)時奸笤,會發(fā)現(xiàn)沒有調用#xxx,而是直接將MARCS字符串化了边灭,這顯然不是我們預期的結果健盒。因此,需要在SPS_PRINT(a)外封裝第二個宏味榛,這個宏什么也不做予跌,直接調用SPS_PRINT(a),這樣频轿,第一層宏會將MARCS展開烁焙,將xxx傳遞給SPS_PRINT,接著SPS_PRINT做正確的字符串化操作膳殷。當時對這個只是一知半解九火,現(xiàn)在才知道他有個專業(yè)的名字--stringification of macro values,借著這個機會岔激,來探索下該技巧的內部機制。

正文

? ? ? ?先來看一段網(wǎng)上搜索到的解釋辱匿,

3.4 Stringification

Sometimes you may want to convert a macro argument into a string constant. Parameters are not replaced inside string constants, but you can use the ‘#’ preprocessing operator instead. When a macro parameter is used with a leading ‘#’, the preprocessor replaces it with the literal text of the actual argument, converted to a string constant. Unlike normal parameter replacement, the argument is not macro-expanded first. This is called stringification.
There is no way to combine an argument with surrounding text and stringify it all together. Instead, you can write a series of adjacent string constants and stringified arguments. The preprocessor will replace the stringified arguments with string constants. The C compiler will then combine all the adjacent string constants into one long string.
Here is an example of a macro definition that uses stringification:

     #define WARN_IF(EXP) \
     do { if (EXP) \
             fprintf (stderr, "Warning: " #EXP "\n"); } \
     while (0)
     WARN_IF (x == 0);
          ==> do { if (x == 0)
                fprintf (stderr, "Warning: " "x == 0" "\n"); } while (0);
The argument for EXP is substituted once, as-is, into the if statement, and once,stringified, into the argument to fprintf. If x were a macro, it would be expanded in the if statement, but not in the string.
The do and while (0) are a kludge to make it possible to write WARN_IF (arg);, which the resemblance of WARN_IF to a function would make C programmers want to do; see Swallowing the Semicolon.
Stringification in C involves more than putting double-quote characters around the fragment. The preprocessor backslash-escapes the quotes surrounding embedded string constants, and all backslashes within string and character constants, in order to get a valid C string constant with the proper contents. Thus, stringifying p = "foo\n"; 
results in "p = \"foo\\n\";". However, backslashes that are not inside string or character constants are not duplicated: ‘\n’ by itself stringifies to "\n".
All leading and trailing whitespace in text being stringified is ignored. Any sequence of whitespace in the middle of the text is converted to a single space in the stringified result. Comments are replaced by whitespace long before stringification happens, so they never appear in stringified text.
There is no way to convert a macro argument into a character constant.
If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros.

     #define xstr(s) str(s)
     #define str(s) #s
     #define foo 4
     str (foo)
          ==> "foo"
     xstr (foo)
          ==> xstr (4)
          ==> str (4)
          ==> "4"
s is stringified when it is used in str, so it is not macro-expanded first. But s is an ordinary argument to xstr, so it is completely macro-expanded before xstr itself is expanded (see Argument Prescan). Therefore, by the time str gets to its argument, it has already been macro-expanded.

? ? ? ?其實說白了絮短,就是預處理器在碰到#指令時昨忆,#的優(yōu)先級會高于宏展開的優(yōu)先級;所以需要額外定義一個外層宏,提前做好宏展開限府!

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末胁勺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子署穗,更是在濱河造成了極大的恐慌嵌洼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麻养,死亡現(xiàn)場離奇詭異,居然都是意外死亡备畦,警方通過查閱死者的電腦和手機许昨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來糕档,“玉大人,你說我怎么就攤上這事俐银±牌拢” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵榆俺,是天一觀的道長坞淮。 經(jīng)常有香客問我回窘,道長市袖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任酒觅,我火速辦了婚禮,結果婚禮上舷丹,老公的妹妹穿的比我還像新娘蜓肆。我一直安慰自己,他們只是感情好仗扬,可當我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布早芭。 她就那樣靜靜地躺著,像睡著了一般逼友。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上帜乞,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天黎烈,我揣著相機與錄音匀谣,去河邊找鬼照棋。 笑死武翎,一個胖子當著我的面吹牛,可吹牛的內容都是我干的宝恶。 我是一名探鬼主播趴捅,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼拱绑,長吁一口氣:“原來是場噩夢啊……” “哼丽蝎!你這毒婦竟也來了?” 一聲冷哼從身側響起屠阻,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤国觉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚜枢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡厂抽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年筷凤,在試婚紗的時候發(fā)現(xiàn)自己被綠了苞七。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹂风,死狀恐怖,靈堂內的尸體忽然破棺而出惠啄,到底是詐尸還是另有隱情,我是刑警寧澤融柬,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布趋距,位于F島的核電站,受9級特大地震影響节腐,放射性物質發(fā)生泄漏摘盆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一骡澈、第九天 我趴在偏房一處隱蔽的房頂上張望掷空。 院中可真熱鬧,春花似錦护锤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至莺褒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間你辣,已是汗流浹背尘执。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留表悬,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓签孔,卻偏偏與公主長得像窘行,于是被迫代替她去往敵國和親罐盔。 傳聞我的和親對象是個殘疾皇子救崔,可洞房花燭夜當晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內容

  • http://www.open-open.com/lib/view/open1390651437117.html ...
    Xtuphe閱讀 1,255評論 0 10
  • 1、c語言的函數(shù)有以下特點: (1)才源程序由函數(shù)組成纬黎,一個主函數(shù)main()+若干其他函數(shù) C程序中的函數(shù)類似文...
    滕王閣序閱讀 1,335評論 0 6
  • 宏定義在C系開發(fā)中可以說占有舉足輕重的作用本今。底層框架自不必說,為了編譯優(yōu)化和方便冠息,以及跨平臺能力,宏被大量使用躏碳,可...
    你好自己閱讀 1,054評論 0 5
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,763評論 0 38
  • 1.OC里用到集合類是什么散怖? 基本類型為:NSArray,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,366評論 0 3