2010-07-05 51 views
15

我要定義一個宏,其包括另一頭文件像這樣:使用#定義爲包括用C另一個文件++/C

#define MY_MACRO (text) #include "__FILE__##_inline.inl" 

這樣當預處理器解析文件person.h,MY_MACRO(blahblah)擴展到

的#include 「person.h.inline.inl」

如何做到這一點的任何提示?

+2

這是不可能的。 – Philipp 2010-07-05 11:55:20

回答

14

除非您運行預處理器兩次,否則不可能使用#define構造其他預處理器指令。

但在您的情況下,即使兩次運行預處理器也無濟於事,因爲#include必須是形式爲"..."<...>的單個字符串。

+1

這是錯誤的,我已經使用過這樣的代碼。他們多次包含該文件,每次在包含宏之前重新定義宏。這導致宏運行多次,每個包含一次。我看到的用例是使用這個技巧製作僞模板的純C代碼。 – 2015-01-27 10:12:40

+0

@GabeSechan你所描述的通常稱爲X宏。但它不會多次運行預處理器。它重新定義宏並多次包含文件。對於某些用例來說,這是一個非常酷的技巧。 – woodtluk 2016-06-14 06:42:48

3

您無法使用預處理器編寫其他預處理器指令。但是,我相信,如果只定義文件名:

#define MY_MACRO(name) "__FILE__##name_inline.inl" 

#include MY_MACRO(name) 

預處理器運行多次,直到沒有進一步的替換它可以使,所以應該首先擴展名,然後的#include引用的文件。

編輯:我只是試過,預處理器不能處理這樣的報價。

#define MY_MACRO(x) <__FILE__##x_inline.inl> 
#include MY_MACRO(foo) 

工作正常,但是<>可能不是你想要的。

編輯2:正如在評論中指出的那樣,__FILE__不能正確擴展,這使得這可能不是你想要的。抱歉。

+1

http://codepad.org/AxNh2h3F顯然''__FILE __ ## name_inline.inl「'是從字面上處理的,但是如果您將其切換爲'#define MY_MACRO(name)<__ FILE__ ## name ## _inline.inl>''那麼你*可以*實際包含一個文件可變。 – 2010-07-05 11:31:09

+0

我不認爲這有效。您提供的宏擴展爲'<__ FILE__x_inline.inl>',而它應該像''。 – sth 2010-07-05 11:40:13

+0

@sth:你說的很對,我錯過了。我試圖將它分解到兩個階段,以及: [代碼]的#define MY_MACRO的(a)__FILE__ ##一個 的#define MY_MACRO_2(b)中 的#include MY_MACRO_2(測試)[/ code] 但這也沒有幫助。 – Vicky 2010-07-05 11:46:21

9

您不能使用__FILE__,因爲它已經被引用,並且#include不支持字符串連接。但是你可以#include後使用宏:

#define STRINGIZE_AUX(a) #a 
#define STRINGIZE(a) STRINGIZE_AUX(a) 
#define CAT_AUX(a, b) a##b 
#define CAT(a, b) CAT_AUX(a, b) 
#define MY_MACRO(file, name) STRINGIZE(CAT(file, CAT(name, _inline.inl))) 
#include MY_MACRO(aaaa, qqq) 

你應該使用等效Boost.Preprocessor宏代替CATSTRINGIZE防止全局命名空間污染。

+0

+1我不確定它是非常醜陋還是非常美麗,但它似乎工作... – Tomas 2010-07-05 14:24:57

+0

是的,它確實設法包括該文件,但仍然必須使用單獨的#包括,也似乎__FILE__是擴展到一個帶引號的字符串,所以可能這是不可能的。 – 2010-07-06 07:43:05

+0

是的,這是不可能的。嘗試重新設計你的應用程序,這樣就沒有必要。 – Philipp 2010-07-06 07:56:29

-5
#if 0 /*Windows*/ 
#define MKDIR_ENABLER <direct.h> 
#define MY_MKDIR(x,y) _mkdir((x)) 
#else /*Linux*/ 
#define MKDIR_ENABLER <sys/stat.h> 
#define MY_MKDIR(x,y) mkdir((x),(y)) 
#endif 

#include MKDIR_ENABLER 

int main(void) 
{ 
    MY_MKDIR("more_bla",0644); 
    return 0; 
} 

此代碼包含適當的mkdir頭文件(因爲它在UNIX和Windows上不同),併爲它引入了一個很好的包裝。

+0

以何種方式提供答案? – dhein 2015-01-27 09:55:49