Re: [問題] PreProcessor的運用

看板C_and_CPP作者 (function(){})()時間9年前發表 (2015/09/08 08:50), 9年前編輯推噓2(205)
留言7則, 3人參與, 最新討論串2/2 (看更多)
※ 引述《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. 當然要是有甚麼奇技淫巧真的可以做到的話就太神奇了 : 問題很奇怪,但小妹一直很困擾,感謝各位解答~~ --

11/06 05:20,
五樓閃尿
11/06 05:20

11/06 05:21,
超☆快速蓋
11/06 05:21

11/06 05:21,
超☆快速蓋蓋
11/06 05:21

11/06 05:21,
超☆快速蓋蓋蓋
11/06 05:21

11/06 05:21,
冒險蓋
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

09/08 16:53, , 1F
簽名檔居然隨機選到 obov, 太神啦
09/08 16:53, 1F

09/08 17:00, , 2F
晚點再補詳細說明 現在沒空
09/08 17:00, 2F

09/08 17:27, , 3F
可以耶!!! 真的太神惹~~請受小妹一拜
09/08 17:27, 3F
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

09/09 17:32, , 4F
你引錯段了, 你應該要引用 ## 這個字串連接的那一段
09/09 17:32, 4F

09/09 17:32, , 5F
這一段講的是 #name 這種用法, 它會把傳進來的 name 內容
09/09 17:32, 5F

09/09 17:33, , 6F
變成字串, 因此它不會進一步下去代換參數內容
09/09 17:33, 6F

09/09 17:33, , 7F
這跟這邊用的 ## 連接不太一樣
09/09 17:33, 7F
對,我引錯段了 上面引的下一章 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
文章代碼(AID): #1Lxg5IxJ (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1Lxg5IxJ (C_and_CPP)