包含#include指令的宏定义

时间:2008-11-05 20:22:48

标签: c++ c macros c-preprocessor

有没有办法定义一个包含#include的宏 指令在其体内?

如果我放 “#include”,它会给出错误

C2162: "expected macro formal parameter"

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

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

任何帮助?

9 个答案:

答案 0 :(得分:20)

就像其他人说的那样,不,你不能在宏中包含#include语句,因为预处理器只进行一次传递。但是,你可以让预处理器与我最近使用的一个粗糙的技巧基本相同。

意识到预处理程序指令不会在宏内部执行任何操作,但是它们会在文件中执行某些操作。因此,您可以将要变换的代码块粘贴到文件中,将其视为宏定义(可以通过其他宏更改的片段),然后在各个位置#include此伪宏文件(make确定它没有包含警卫!)。它的行为与宏不完全相同,但它可以实现一些非常类似于宏的结果,因为#include基本上只是将一个文件的内容转储到另一个文件中。

例如,考虑包含许多类似命名的标题组。将它们全部写出来,或者甚至是自动生成它们都很繁琐。您可以通过执行以下操作来部分自动化其包含:

Helper宏标题:

/* 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已更改),正如Bing Jian的回答所要求的那样:macro definition containing #include directive

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

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

答案 1 :(得分:10)

我不会争论它的优点,但是freetype(www.freetype.org)会做以下事情:

#include FT_FREETYPE_H

他们在其他地方定义FT_FREETYPE_H

答案 2 :(得分:6)

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

答案 3 :(得分:5)

我相信C / C ++预处理器只对代码进行一次传递,所以我认为这不会起作用。您可能能够通过宏将“#include”放在代码中,但编译器会阻塞它,因为它不知道如何处理它。对于你要做的工作,预处理器必须对文件进行第二次传递才能获取#include。

答案 4 :(得分:4)

我也想这样做,原因如下:

如果您使用C或C ++进行编译,某些头文件(特别是OpenMPI中的mpi.h)的工作方式会有所不同。我正在链接到我的C ++程序中的C MPI代码。要包含标题,我会照常做到:

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

但这不起作用,因为即使在C链接中仍然定义__cplusplus。这意味着blah.h包含的mpi.h开始定义模板,编译器死了,说你不能使用带有C链接的模板。

因此,我在blah.h中要做的就是替换

#include <mpi.h>

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

值得注意的是,这不仅仅是mpi.h。因此,我想定义一个宏INCLUDE_AS_C,它为指定的文件执行上述操作。但我想这不起作用。

如果有人能找到另一种方法来实现这一点,请告诉我。

答案 5 :(得分:3)

我认为你没事,因为我从

获得这项任务似乎是不可能的

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

  

不,C ++中的预处理程序指令   (和C)没有反思性。

     

Pawel 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”中写入了特定于任务的代码。

答案 6 :(得分:1)

为什么宏需要#include?如果你是#include'ing宏所在的任何文件,你可以把#include放在宏上面与所有其余的#include语句,并且一切都应该是好的和花花公子。

我认为没有理由让宏包含任何不能包含在文件中的内容。

答案 7 :(得分:0)

我不知道你究竟想做什么,但它看起来像你想要的是模板化的功能。

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

答案 8 :(得分:-8)

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

myfile.c文件:

#include "standardAppDefs.h"
#myStandardIncludeMacro

standardAppDefs.h:

#define myStandardIncludeMacro #include <foo.h>

为什么不说:

myfile.c文件:

#include "standardAppDefs.h"

standardAppDefs.h:

#include <foo.h>

忘了宏?