2010-07-05 55 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