2008-11-05 114 views
25

有没有办法定义一个宏,其中可能包含指令在其正文中的#include 指令?包含#include指令的宏定义

如果我只是把 的 “#include”,它给了错误

C2162: "expected macro formal 

参数”

因为在这里我没有使用#连接字符串。
如果我使用 “\# include”那么我收到以下两个错误:

error C2017: illegal escape sequence 
error C2121: '#' : invalid character : possibly the result of a macro expansion 

有什么帮助?

回答

1

宏为什么需要#include?如果你#包含宏的任何文件,你可以将#include放在宏的上面,并包含#include语句的其余部分,并且所有内容都应该很好,并且很花哨。

我看不出有什么理由让宏包含任何不能包含在文件中的东西。

5

我相信C/C++预处理器只会对代码进行一次遍历,所以我认为这不会起作用。你可能会得到一个“#include”被宏放在代码中,但编译器会窒息它,因为它不知道该怎么做。对于你要做的工作,预处理器必须对文件进行第二遍处理,以获取#include。

-7

传染性是正确的 - 如果你正在做的:

myfile.c文件:

#include "standardAppDefs.h" 
#myStandardIncludeMacro 

standardAppDefs.h:

#define myStandardIncludeMacro #include <foo.h> 

为什么不直接说:

myFile.c:

#include "standardAppDefs.h" 

standardAppDefs.h:

#include <foo.h> 

,忘记了宏?

3

我认为你是在没事这项任务似乎是不可能的,因为我也是从

http://groups.google.com/group/comp.lang.c++/browse_thread/thread/03d20d234539a85c#

没有得到,在C++ (和C)预处理指令是不反光。

帕维尔Dziepak

不管怎么说,这背后的尝试的原因是,我想作以下 反复使用的代码段宏:

void foo(AbstractClass object) 
{ 
    switch (object.data_type()) 
    { 
    case AbstractClass::TYPE_UCHAR : 
     { 
     typedef unsigned char PixelType; 
     #include "snippets/foo.cpp" 
     } 
     break; 
    case AbstractClass::TYPE_UINT: 
     { 
     typedef unsigned int PixelType; 
     #include "snippets/foo.cpp" 
     } 
     break; 
    default: 
     break; 
    } 
} 

另一项任务,我需要具有类似的功能

void bar(AbstractClass object) 

我在哪里将

#include "snippets/bar.cpp" 

当然,它是在写入任务特定代码的“snippets/foo.cpp”和“snippets/bar.cpp”中。

+2

你应该看看模板(如stbuton建议)。你当然应该避免需要这样做。 – 2008-11-05 22:42:55

+0

作为一般规则,您应该将所有#include语句放在同一个地方(通常是顶部)。它使维护和调试代码更简单。 – helloandre 2008-11-06 01:30:20

+0

我有一个基本上你想做的事情(使用预处理器)有点疯狂的方式;请参阅我的回答:) http://stackoverflow.com/a/27830271/1447953 – 2015-01-07 23:17:27

9

我不会说优点吧,但FreeType的(www.freetype.org)执行以下操作:

#include FT_FREETYPE_H 

他们定义FT_FREETYPE_H别处

+8

这是在标准中明确允许的,因此只要FT_FREETYPE_H扩展为或“header.h”形式,便携便携。 – 2008-11-05 22:42:11

0

我不知道你是什么实际试图做,但它看起来像你可能想要的是模板功能。

这样PixelType只是代码块的模板参数。

4

我也想做到这一点,和这里的原因:

一些头文件(特别的openmpi mpi.h)的工作方式不同,如果你是使用C或C++编译。我正在链接到来自C++程序的C MPI代码。要包含头,我做平常:

extern "C" { 
#include "blah.h" 
} 

但由于__cplusplus甚至在C链接仍然定义这不起作用。这意味着由blah.h包含的mpi.h开始定义模板,并且编译器会死掉,说你不能使用C链接模板。

因此,我有什么在blah.h做是

#ifdef __cplusplus 
#undef __cplusplus 
#include <mpi.h> 
#define __cplusplus 
#else 
#include <mpi.h> 
#endif 

更换

#include <mpi.h> 

值得注意的是它不只是mpi.h,这是否病态的东西。因此,我想定义一个宏INCLUDE_AS_C,它为指定的文件做了上述操作。但我想这是行不通的。

如果有人可以找出另一种方法来完成这一点,请让我知道。

6

由于宏扩展,C和C++语言明确禁止形成预处理器指令。这意味着您不能在宏替换列表中包含预处理器指令。如果你试图通过串联(和类似的技巧)“构建”一个新的预处理器指令来欺骗预处理器,那么行为是不确定的。

14

所以像其他人说的那样,不可以在宏中包含#include语句,因为预处理器只会传递一次。但是,您可以使预处理器使用最近发现自己使用的粗糙技巧来做基本相同的事情。

认识到预处理器指令不会在宏内执行任何操作,但它们会在文件中执行某些操作。所以,你可以将你想要改变的代码块粘贴到一个文件中,把它看作是一个宏定义(可以用其他宏修改),然后在不同的地方包含这个伪宏文件(make确定它没有包括警卫!)。它的行为不像一个宏,但它可以实现一些非常类似宏的结果,因为#include基本上只是将一个文件的内容转储到另一个文件中。

例如,考虑包含许多类似命名的标头,这些标头会分组。将它们全部写出来,或者甚至它们是自动生成的都很乏味。

辅助宏头:

/* tools.hpp */ 

#ifndef __TOOLS_HPP__ 
#def __TOOLS_HPP__ 

// Macro for adding quotes 
#define STRINGIFY(X) STRINGIFY2(X)  
#define STRINGIFY2(X) #X 

// Macros for concatenating tokens 
#define CAT(X,Y) CAT2(X,Y) 
#define CAT2(X,Y) X##Y 
#define CAT_2 CAT 
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z)) 
#define CAT_4(A,X,Y,Z) CAT(A,CAT_3(X,Y,Z)) 
// etc... 

#endif 

伪宏文件

/* pseudomacro.hpp */ 

#include "tools.hpp" 
// NO INCLUDE GUARD ON PURPOSE 
// Note especially FOO, which we can #define before #include-ing this file, 
// in order to alter which files it will in turn #include. 
// FOO fulfils the role of "parameter" in this pseudo-macro. 

#define INCLUDE_FILE(HEAD,TAIL) STRINGIFY(CAT_3(HEAD,FOO,TAIL)) 

#include INCLUDE_FILE(head1,tail1.hpp) // expands to #head1FOOtail1.hpp 
#include INCLUDE_FILE(head2,tail2.hpp) 
#include INCLUDE_FILE(head3,tail3.hpp) 
#include INCLUDE_FILE(head4,tail4.hpp) 
// etc.. 

#undef INCLUDE_FILE 

源文件

/* mainfile.cpp */ 

// Here we automate the including of groups of similarly named files 

#define FOO _groupA_ 
#include "pseudomacro.hpp" 
// "expands" to: 
// #include "head1_groupA_tail1.hpp" 
// #include "head2_groupA_tail2.hpp" 
// #include "head3_groupA_tail3.hpp" 
// #include "head4_groupA_tail4.hpp" 
#undef FOO 

#define FOO _groupB_ 
#include "pseudomacro.hpp" 
// "expands" to: 
// #include "head1_groupB_tail1.hpp" 
// #include "head2_groupB_tail2.hpp" 
// #include "head3_groupB_tail3.hpp" 
// #include "head4_groupB_tail4.hpp" 
#undef FOO 

#define FOO _groupC_ 
#include "pseudomacro.hpp" 
#undef FOO 

// etc. 

这些包括可能您可以通过做这样的事情部分自动将其列入甚至是在你想重复的代码块的中间(用FOO修改),就像一个由冰坚请求:macro definition containing #include directive

我还没有广泛使用这个技巧,但它使我的工作完成。显然,它可以根据需要扩展为具有尽可能多的“参数”,并且您可以在其中运行您喜欢的任何预处理器命令,并生成实际的代码。你不能使用它创建的东西作为另一个宏的输入,就像你可以使用普通的宏一样,因为你不能将include包含在宏中。但它可以进入另一个伪宏:)。

其他人可能对其他限制有一些评论,并可能出错:)。