字符串化宏(名稱)比較,以宏的字符串化(展開)值:
#include <iostream>
#include <cstring>
#define TRACE_STRINGIFY(item) "" #item
#define TRACE(macro, message) \
do { \
if (strcmp("" #macro, TRACE_STRINGIFY(macro))) \
std::cout << message << "\n"; \
} while (0)
的"" # macro
擴展爲宏名稱作爲一個字符串,而TRACE_STRINGIFY(macro)
第一擴展宏,然後stringifies的結果。如果兩者不同,則macro
必須是預處理器宏。
這種方法對於自己定義的宏,即#define FOO FOO
確實失敗。這些宏不會被檢測爲預處理器宏。
大多數編譯器應該能夠完全優化兩個字符串文字的比較。 GNU GCC(g ++)4.8.2甚至可以使用-O0
(就像C的gcc一樣 - 同樣的方法在C中也很明顯)。
這種方法適用於類函數宏,但只適用於保留括號(和適當數量的逗號,如果宏需要多個參數)並且沒有爲其自身定義(例如#define BAR(x) BAR(x)
)。
例如:
#define TEST1 TEST1
#define TEST3
#define TEST4 0
#define TEST5 1
#define TEST6 "string"
#define TEST7 ""
#define TEST8 NULL
#define TEST9 TEST3
#define TEST10 TEST2
#define TEST11(x)
#define TEST13(x,y,z) (x, y, z)
int main(void)
{
TRACE(TEST1, "TEST1 is defined");
TRACE(TEST2, "TEST2 is defined");
TRACE(TEST3, "TEST3 is defined");
TRACE(TEST4, "TEST4 is defined");
TRACE(TEST5, "TEST5 is defined");
TRACE(TEST6, "TEST6 is defined");
TRACE(TEST7, "TEST7 is defined");
TRACE(TEST8, "TEST8 is defined");
TRACE(TEST9, "TEST9 is defined");
TRACE(TEST10, "TEST10 is defined");
TRACE(TEST11, "TEST11 is defined");
TRACE(TEST12, "TEST12 is defined");
TRACE(TEST13, "TEST13 is defined");
TRACE(TEST14, "TEST14 is defined");
TRACE(TEST1(), "TEST1() is defined");
TRACE(TEST2(), "TEST2() is defined");
TRACE(TEST3(), "TEST3() is defined");
TRACE(TEST4(), "TEST4() is defined");
TRACE(TEST5(), "TEST5() is defined");
TRACE(TEST6(), "TEST6() is defined");
TRACE(TEST7(), "TEST7() is defined");
TRACE(TEST8(), "TEST8() is defined");
TRACE(TEST9(), "TEST9() is defined");
TRACE(TEST10(), "TEST10() is defined");
TRACE(TEST11(), "TEST11() is defined");
TRACE(TEST12(), "TEST12() is defined");
TRACE(TEST13(,,), "TEST13(,,) is defined");
TRACE(TEST14(,,), "TEST14(,,) is defined");
return 0;
}
其輸出
TEST3 is defined
TEST4 is defined
TEST5 is defined
TEST6 is defined
TEST7 is defined
TEST8 is defined
TEST9 is defined
TEST10 is defined
TEST3() is defined
TEST4() is defined
TEST5() is defined
TEST6() is defined
TEST7() is defined
TEST8() is defined
TEST9() is defined
TEST10() is defined
TEST11() is defined
TEST13(,,) is defined
換句話說,該TEST1
符號不被識別爲定義(因爲它被定義爲本身),也不是TEST11
或TEST13
而不括號。這是這種方法的侷限性。
使用括號表單適用於所有無參數宏(除TEST1
之外,即爲自己定義的那些宏)和所有單參數宏。如果宏需要多個參數,則需要使用正確數量的逗號,否則(例如,如果嘗試TRACE(TEST13(), "...")
)會得到編譯時錯誤:「宏TEST13
需要3個參數,只有1個參數爲」「或類似的。
有問題?
你可以使用一個變量,並依靠編譯器來優化條件嗎? – BonzaiThePenguin 2014-09-29 12:27:12
@Bonzai企鵝:不確定你的意思。請舉例。 – gexicide 2014-09-29 12:28:35