作者azureblaze (AzureBlaze)
看板C_and_CPP
標題Re: [情報] C++大師認證
時間Fri Apr 26 09:25:19 2013
※ 引述《windows2k (程式宅 <囧>)》之銘言:
: 我又來問問題了...
: 作業四裡面有個範例
: #define f(x) 1 x
: #define g(x) 2 x
: g(f)(g)(3)
: 推導最後的結果是 2 1 g(3)
: 我的問題是為什麼最後的g不被替換掉...雖然有寫解釋但我看不懂 orz
: 試了一下gcc跟clang
: 這範例的結果都是 2 1 2 3
: 有人可以幫忙解釋一下嘛?謝謝
PA4大概是目前五個PA中最難看懂到底要做什麼的...
macro部份的標準真的是一團亂,因為他是經過40年的大家亂加東西後
才被硬寫出標準來的。
這部份有很多implemention-defined behavior,所以和gcc不一樣很正常
////////////////////////////
第一個規則是:
「如果macro代換過程中遇到跟該macro同名的token,該token不會被代換
而如果接下來的多層代換中再度碰到與這個macro同名的token,也不會代換」
課程中定義所為的多層代換(nested replacement):
如果觸發Y的token為X的代換結果,那XY互相就為多層代換
以黑名單的方式實做可以將上面翻譯成
「所有macro代換出來的token,都會黑名單該macro的名稱
同時繼承觸發此macro的token的黑名單」
所以:
//token正下方為該token的黑名單內容
g(f)(g)(3)
=>
//代換g(f)
2 f(g)(3)
g g
//2和f由g產生因此黑掉g
=>
//代換f(g)
2 1 g(3)
g g g
f f
//1和g由f產生,因此黑掉f
//同時繼承f的黑名單[g]
接著g(3)因為g已經被黑名單了所以不會進行代換
//////////////////////////////////////////
第二個規則是:
「如果一個token曾經因為多層代換而沒被代換,則該token就算經過參數代換也
永遠不會被代換」
函數式的macro的參數會先被單獨抽出來,代換完後再放回macro
在放回macro前,他的黑名單會先被清乾淨。
但是在過程中因為黑名單而沒被代換的token會被留下終生不得代換的記號
也就是水桶期間發文所以被BAN IP
例如
#define z z[0]
#define f(x) 1 x
f(z)
////
f(z)
=> 抽出參數z,單獨代換
f(x:= z )
=>
f(x:= z[0] )
zzzz
=> z[0]是代換產生物,因此重新套macro一遍
f(x:= z[0] )
zzzz
*
//z被黑名單又想被代換,因此加上不得代換標記
=> 代換f(x),把x的黑名單清乾淨
1 x x:= z[0]
f f *
=> 放入x
1 z[0]
f ffff
*
=>重新套macro
1 z[0]
f ffff
*
//z被標為不得代換,因此沒被代換
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.168.88.7
推 windows2k:謝謝 04/26 12:27
→ remmurds:說真的 能不用macro就盡量不要用它 04/27 21:39
→ suhorng:@remmurds: 可是作業不得不弄macro XD 04/27 23:16
→ azureblaze:這個作業告訴我們: 去你的macro 04/27 23:38