当前位置:  开发笔记 > 编程语言 > 正文

包含#include指令的宏定义

如何解决《包含#include指令的宏定义》经验,为你挑选了4个好方法。

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

如果我只是把" #include",它给出了错误

C2162: "expected macro formal parameter"

因为在这里我不是#用来连接字符串.
如果我使用" \# include",那么我收到以下两个错误:

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

有帮助吗?



1> Ben Farmer..:

就像其他人说的那样,不,你不能在宏中包含#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的答案要求:包含#include指令的宏定义

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

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


听起来很棒,但理论上它没有在标准中定义,它依赖于编译器实现.请参见http://stackoverflow.com/questions/20524491/preprocessor-concatenation-for-include-path/20524959#20524959

2> Dan Hewett..:

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

#include FT_FREETYPE_H

他们在其他地方定义FT_FREETYPE_H


这在标准中是明确允许的,因此只要FT_FREETYPE_H扩展为或"header.h"形式,它就是可移植的.

3> AnT..:

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



4> Herms..:

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

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有