2017-03-07 21 views
2

我已經定義了一個類似對象的宏和一個類似函數的宏(從this問題)。爲什麼我無法將類似對象的宏粘貼到函數中?

#define SYSTEM windows 
#define CALL(function, ...) (function)(__VA_ARGS__) 

根據這個定義,CALL(foo, arg1, arg2)變成foo(arg1, arg2)

我想要CALL(foo, args)變成x__foo(args),xSYSTEM定義的任何值。

我曾嘗試:

#define CALL(function, ...) SYSTEM##__function(__VA_ARGS__) 
#define CALL(function, ...) (SYSTEM)##__##(function)(__VA_ARGS__) 
#define CALL(function, ...) ((SYSTEM)##__##(function)(__VA_ARGS__) 

他們都導致編譯器錯誤。如何連接SYSTEM,__function的值?

回答

6

您將需要更多級別的間接來連接(粘貼)這些值。 C預處理器試圖粘貼,看起來好像是。如果它看到的是一個宏或一個傳遞給函數的值,它並沒有意識到這一點。

  • MACRO##SOMETHINGELSE將產生MACROSOMETHINGELSE
  • (MACRO)##SOMETHINGELSE編譯時會導致錯誤,因爲預處理器正試圖粘貼括號。
  • SOMETHINGELSE##VALUEPASSEDTOMACRO將導致。

顯然,這些都不是你想要的。要添加將類對象宏值和傳遞給類似函數宏的值進行連接所需的間接引用,請再使用兩個定義。

#define _cat(x, y) x ## y 
#define cat(x, y) _cat(x, y) 

然後,您可以定義CALL以符合您的需求。

#define SYSTEM windows 
#define CALL(function, ...) cat(cat(SYSTEM, __), function) (__VA_ARGS__) 

寫作CALL(foobar, x, y)電話windows__foobar(x, y)達到目標。

4
#define SYSTEM windows 
#define PASTE_CALL(prefix, function, ...) prefix ## __ ## function(__VA_ARGS__) 
#define EVAL_CALL(prefix, function, ...) PASTE_CALL(prefix, function, __VA_ARGS__) 
#define CALL(function, ...) EVAL_CALL(SYSTEM, function, __VA_ARGS__) 

CALL(foo, arg1, arg2) 

如所希望的,這產生:

# 1 "paste.c" 
# 1 "<built-in>" 
# 1 "<command-line>" 
# 1 "paste.c" 





windows__foo(arg1, arg2) 
相關問題