看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《Makiyo5566 (五五六六我最棒)》之銘言: : 最近小妹我遇到一個問題想請問一下 : (敘述有點長,可以直接end看問題) : 想用preprocessor讓code做到無痛切換環境 : ==================== : 環境1: : env1->var1, env1->qq1, ... : 環境2: : env2_var1, env2_qq1, ... : ==================== : 目前我是運用define: : env1: : #define GG(name) env1->##name : env2: : #define GG(name) env2_##name : 本體Code: : GG(var1), GG(qq1), ... : 就可以讓code自動切換 : 但如果 : 環境1: : env1->var1 : 環境2: : ENV2_VAR1 : 問題來了: : 我想要靠 : GG(var1) 生出 ENV2_VAR1 (大寫) : 有什麼辦法嗎? : 目前想到的是用兩次define,可是precompiler沒有次序性,所以失敗: : #define var1 VAR1 : #define GG(name) ENV2_##name : preproc GG(var1)出來還是 ENV2_var1 不會是預期的 ENV2_VAR1 : 問題一: : 1. 有沒有技巧可以調整predefine ## 的大小寫 : 2. 有沒有方法讓preproc.像上面能夠有關聯性的執行(好像不太可能?) preprocessor 不可能轉換大小寫 但是你原先的想法是可行的,只需要加個 proxy 就好 範例: #define var1 VAR1 #define GG(name) ENV_##name #define GG_proxy(name) GG(name) GG_proxy(var1) GG_proxy(test) 用 gcc -E filename.c 可以看到 preprocess 後結果 : 問題二: : 要怎麼達到這種效果(就是想要取代有意義的字,如member ptr): : #define env1->name env2_##name 我認為不太可能達成 preprocessor 把單一字元分為 identifier, punctuator... 等等不同 class 而 #define 後面只能接 identifier, 以 gcc 官方文件來講的話就是 any sequence of letters, digits, or underscores, which begins with a letter or underscore. 當然要是有甚麼奇技淫巧真的可以做到的話就太神奇了 : 問題很奇怪,但小妹一直很困擾,感謝各位解答~~ --
obov:五樓閃尿11/06 05:20
obov:超☆快速蓋11/06 05:21
obov:超☆快速蓋蓋11/06 05:21
obov:超☆快速蓋蓋蓋11/06 05:21
xyz4594:冒險蓋11/06 05:21
obov:幹拎娘插三小 obov:連閃尿都要插 11/06 05:22 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.117.181.25 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1441702226.A.ED3.html
s25g5d4: 簽名檔居然隨機選到 obov, 太神啦 09/08 16:53
s25g5d4: 晚點再補詳細說明 現在沒空 09/08 17:00
Makiyo5566: 可以耶!!! 真的太神惹~~請受小妹一拜 09/08 17:27
GCC, The C Preprocessor, Macros, Stringification 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. 只要 macro 參數含有前綴 #, preprocessor 就不會對此參數展開 macro 所以 #define GG(name) ENV_##name 含有 #, 故不會再展開 (與其他 macro 連動) 加了一個 proxy 就可以避掉這個問題 #define GG_proxy(name) GG(name) 在這裡由於 name 沒有 # 前綴 name 會先被展開,接著才展開 GG(name) ※ 編輯: s25g5d4 (59.127.251.59), 09/09/2015 13:47:36
LPH66: 你引錯段了, 你應該要引用 ## 這個字串連接的那一段 09/09 17:32
LPH66: 這一段講的是 #name 這種用法, 它會把傳進來的 name 內容 09/09 17:32
LPH66: 變成字串, 因此它不會進一步下去代換參數內容 09/09 17:33
LPH66: 這跟這邊用的 ## 連接不太一樣 09/09 17:33
對,我引錯段了 上面引的下一章 Concatenation 有提到 If either of the tokens next to an ‘##’ is a parameter name, it is replaced by its actual argument before ‘##’ executes. As with stringification, the actual argument is not macro-expanded first. 所以 ## 會跟 # 一樣,不做 macro 展開 ※ 編輯: s25g5d4 (59.127.251.59), 09/09/2015 18:13:36