第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

如何與C預(yù)處理器連接兩次并展開宏(如“arg#宏”中的宏)?

如何與C預(yù)處理器連接兩次并展開宏(如“arg#宏”中的宏)?

C C++
慕萊塢森 2019-06-05 14:28:08
如何與C預(yù)處理器連接兩次并展開宏(如“arg#宏”中的宏)?我正試圖編寫一個(gè)程序,其中某些函數(shù)的名稱依賴于某個(gè)宏變量的值,其宏如下所示:#define VARIABLE 3#define NAME(fun) fun ## _ ## VARIABLEint NAME(some_function)(int a);不幸的是,宏NAME()把它變成int some_function_VARIABLE(int a);而不是int some_function_3(int a);因此,這顯然是錯(cuò)誤的做法。幸運(yùn)的是,變量的不同可能值的數(shù)目很小,所以我可以簡(jiǎn)單地做一個(gè)#if VARIABLE == n并分別列出所有案例,但我想知道是否有一個(gè)聰明的方法來做到這一點(diǎn)。
查看完整描述

2 回答

?
臨摹微笑

TA貢獻(xiàn)1982條經(jīng)驗(yàn) 獲得超2個(gè)贊

標(biāo)準(zhǔn)C預(yù)處理器

$?cat?xx.c#define?VARIABLE?3#define?PASTER(x,y)?x?##?_?##?y#define?EVALUATOR(x,y)??PASTER(x,y)#define?NAME(fun)?EVALUATOR(fun,?VARIABLE)
extern?void?NAME(mine)(char?*x);$?gcc?-E?xx.c#?1?"xx.c"#?1?"<built-in>"#?1?"<command-line>"#?1?"xx.c"extern?void?mine_3(char?*x);$

兩級(jí)間接

為什么這需要兩個(gè)層次的間接。輕率的答案是,因?yàn)檫@是標(biāo)準(zhǔn)要求它工作的方式;你往往會(huì)發(fā)現(xiàn),你也需要與字符串操作符一樣的技巧。

C99標(biāo)準(zhǔn)第6.10.3節(jié)涵蓋“宏替換”,6.10.3.1涵蓋“參數(shù)替換”。

在確定了調(diào)用類似于函數(shù)的宏的參數(shù)之后,就會(huì)發(fā)生參數(shù)替換。替換列表中的參數(shù),除非前面有###預(yù)處理令牌或后面是##預(yù)處理令牌(見下文),在展開其中包含的所有宏后,將被相應(yīng)的參數(shù)替換。在被替換之前,每個(gè)參數(shù)的預(yù)處理標(biāo)記都會(huì)被宏完全替換,就好像它們構(gòu)成了預(yù)處理文件的其余部分一樣;沒有其他的預(yù)處理標(biāo)記可用。

在調(diào)用中NAME(mine),該參數(shù)為“my”;它被完全展開為“my”;然后將其替換為替換字符串:

EVALUATOR(mine,?VARIABLE)

現(xiàn)在,宏評(píng)估器被發(fā)現(xiàn),參數(shù)被隔離為‘my’和‘Variable’;后者隨后被完全展開為‘3’,并被替換成替換字符串:

PASTER(mine,?3)

其他規(guī)則(6.10.3.3‘#操作符’)涵蓋了這方面的操作:

如果在類似函數(shù)的宏的替換列表中,參數(shù)緊跟在##預(yù)處理令牌,將參數(shù)替換為相應(yīng)參數(shù)的預(yù)處理令牌序列;[.]

對(duì)于類似對(duì)象的宏調(diào)用和類似函數(shù)的宏調(diào)用,在重新檢查替換列表以獲得要替換的更多宏名稱之前,##替換列表中的預(yù)處理令牌(不是從參數(shù)中刪除)被刪除,并將前面的預(yù)處理令牌與以下預(yù)處理令牌連接起來。

因此,替換列表包含x緊隨其后##還有##緊隨其后y因此,我們有:

mine?##?_?##?3

和消除##任何一方的令牌和連接令牌將“my”與“_”和“3”組合在一起,從而產(chǎn)生如下結(jié)果:

mine_3

這是期望的結(jié)果。


如果我們看一下最初的問題,代碼(修改為使用‘my’而不是‘SomeFunction’):

#define?VARIABLE?3#define?NAME(fun)?fun?##?_?##?VARIABLENAME(mine)

關(guān)于名字的論點(diǎn)顯然是“我的”,而且已經(jīng)完全擴(kuò)展了。
按照6.10.3.3的規(guī)則,我們認(rèn)為:

mine?##?_?##?VARIABLE

當(dāng)##運(yùn)算符被刪除,映射到:

mine_VARIABLE

和問題中的報(bào)道完全一樣。


傳統(tǒng)C預(yù)處理器

對(duì)于沒有令牌粘貼操作符的傳統(tǒng)C預(yù)處理程序,有什么方法可以做到嗎?##?

也許,也許不是-這取決于預(yù)處理程序。標(biāo)準(zhǔn)預(yù)處理器的優(yōu)點(diǎn)之一是它具有可靠工作的功能,而對(duì)于預(yù)標(biāo)準(zhǔn)的預(yù)處理器則有不同的實(shí)現(xiàn)。一個(gè)要求是,當(dāng)預(yù)處理器替換一個(gè)注釋時(shí),它不會(huì)像ANSI預(yù)處理器所要求的那樣生成一個(gè)空間。GCC(6.3.0)C預(yù)處理器滿足這一要求;XCode 8.2.1中的Clang預(yù)處理器不滿足這一要求。

當(dāng)它起作用時(shí),它就完成了(x-paste.c):

#define?VARIABLE?3#define?PASTE2(x,y)?x/**/y#define?EVALUATOR(x,y)?PASTE2(PASTE2(x,_),y)#define?NAME(fun)?EVALUATOR(fun,VARIABLE)
extern?void?NAME(mine)(char?*x);

請(qǐng)注意,在fun,VARIABLE-這很重要,因?yàn)槿绻嬖?,則會(huì)將其復(fù)制到輸出中,而您的結(jié)果是mine_ 3作為名稱,當(dāng)然,這在語(yǔ)法上是無效的。(現(xiàn)在,請(qǐng)把頭發(fā)還給我好嗎?)

GCC 6.3.0(跑步)cpp -traditional x-paste.c),我明白:

#?1?"x-paste.c"#?1?"<built-in>"#?1?"<command-line>"#?1?"x-paste.c"extern?void?mine_3(char?*x);

使用XCode 8.2.1中的Clang,我得到:

#?1?"x-paste.c"#?1?"<built-in>"?1#?1?"<built-in>"?3#?329?"<built-in>"?3#?1?"<command?line>"?1#?1?"<built-in>"?2#?1?"x-paste.c"
?2extern?void?mine?_?3(char?*x);

那些空間破壞了一切。我注意到這兩個(gè)預(yù)處理器都是正確的;不同的預(yù)標(biāo)準(zhǔn)預(yù)處理器顯示了這兩種行為,這使得令牌粘貼在嘗試移植代碼時(shí)非常煩人和不可靠。標(biāo)準(zhǔn)##符號(hào)從根本上簡(jiǎn)化了這一點(diǎn)。

也許還有其他方法可以做到這一點(diǎn)。然而,這是行不通的:

#define?VARIABLE?3#define?PASTER(x,y)?x/**/_/**/y#define?EVALUATOR(x,y)?PASTER(x,y)#define?NAME(fun)?EVALUATOR(fun,VARIABLE)extern?
void?NAME(mine)(char?*x);

GCC:

#?1?"x-paste.c"#?1?"<built-in>"#?1?"<command-line>"#?1?"x-paste.c"extern?void?mine_VARIABLE(char?*x);

接近但沒有骰子。YMMV,當(dāng)然,取決于您使用的預(yù)標(biāo)準(zhǔn)預(yù)處理器。坦率地說,如果您被一個(gè)不合作的預(yù)處理器困住了,那么安排使用標(biāo)準(zhǔn)C預(yù)處理器代替預(yù)標(biāo)準(zhǔn)處理器(通常有一種適當(dāng)配置編譯器的方法)可能比花很多時(shí)間想出一種方法來完成這一工作要簡(jiǎn)單得多。


查看完整回答
反對(duì) 回復(fù) 2019-06-05
?
30秒到達(dá)戰(zhàn)場(chǎng)

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超6個(gè)贊

#define VARIABLE 3

#define NAME2(fun,suffix) fun ## _ ## suffix

#define NAME1(fun,suffix) NAME2(fun,suffix)

#define NAME(fun) NAME1(fun,VARIABLE)


int NAME(some_function)(int a);

老實(shí)說,你不想知道為什么會(huì)這樣。如果你知道為什么會(huì)起作用,你就會(huì)變成那個(gè)家伙在工作中,誰知道這類事情,每個(gè)人都會(huì)來問你問題。=)


編輯:如果你真的想知道它的工作原理,我很樂意發(fā)表一個(gè)解釋,假設(shè)沒有人比我強(qiáng)。


查看完整回答
反對(duì) 回復(fù) 2019-06-05
  • 2 回答
  • 0 關(guān)注
  • 759 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)