Re: [問題] PreProcessor的運用
看板C_and_CPP作者s25g5d4 (function(){})()時間9年前發表 (2015/09/08 08:50), 9年前編輯推噓2(2推 0噓 5→)留言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
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
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
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):