C 编程:预处理器,包含宏中的文件
如果我能找到一种方法来做类似的事情,我就可以在应用程序中删除数百行代码,并显着提高可维护性。有人有什么想法吗?
#include <stdio.h>
int main( )
{
#define include_all_files(root) \
#include #root "1.h" \
#include #root "2.h" \
#include #root "3.h" \
#include #root "4.h"
include_all_files( first_library )
include_all_files( second_library )
include_all_files( third_library )
return 0;
}
编辑:
我很欣赏这些回应,我的例子似乎导致了努力的误导,所以这就是我实际上试图解决的问题:
我正在实现一个有限状态机。通过命名约定,我已经将添加状态变得非常简单:
STATE(initial_screen)
#include "initial_screen.state"
END_STATE
STATE(login)
#include "login.state"
END_STATE
但是,如果我可以回答最初的问题,我可以将其重构为简单的内容:
ADD_STATE(initial_screen)
ADD_STATE(login)
这是因为文件名和状态名称,所有底层布线和其他一切都遵循类似的约定。但是,我无法弄清楚如何根据宏中收到的令牌来实现包含文件。
If I could find a way to do something similar to this, I could cut out hundreds of lines of code in my application, and dramatically increase maintainability. Anyone have any ideas?
#include <stdio.h>
int main( )
{
#define include_all_files(root) \
#include #root "1.h" \
#include #root "2.h" \
#include #root "3.h" \
#include #root "4.h"
include_all_files( first_library )
include_all_files( second_library )
include_all_files( third_library )
return 0;
}
EDIT:
I appreciate the responses, my example seems to be causing a misdirection in effort, so here is the problem I am actually trying to solve:
I am implementing a finite state machine. Through naming conventions, I have gotten it to be as simple to add a state as:
STATE(initial_screen)
#include "initial_screen.state"
END_STATE
STATE(login)
#include "login.state"
END_STATE
However, if I could answer the original question, I could refactor this down to something as simple as:
ADD_STATE(initial_screen)
ADD_STATE(login)
This is because the file name and the state name, and all the underlying wiring and everything else all follow similar conventions. However, I cannot figure out how to implement the include file based on the token received in a macro.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
为什么不直接创建一个头文件,它本身
#include
包含库的所有其他头文件?然后,对于每个库,您只需包含该库的一个元标头。Why not just create a header file that itself
#include
s all of the other header files for the library? Then for each library you'd just include that library's one meta-header.不幸的是,这超出了 C 预处理器的能力。
您是否考虑过使用类似 m4 的东西?
Unfortunately, this is beyond the capabilities of the C preprocessor.
Have you considered using something like m4 instead?
为了解决您澄清的问题,您可以重构
initial_screen.state
和login.state
,以便它们以STATE()
开头并以 <代码>END_STATE。然后你可以这样做:...这相当于你所追求的 - 它只是一个
#include
而不是ADD_STATE
。To solve your clarified problem, you could just refactor
initial_screen.state
andlogin.state
so that they start withSTATE()
and end withEND_STATE
. Then you can just do:...which is equivalent to what you're after - it's just an
#include
instead of anADD_STATE
.在文件includes.h
中 在所有其他文件中
In file includes.h
In all other files
#include 预处理指令本身与宏评估在同一步骤中处理,这可能不起作用。我不相信预处理可以递归。 (或者就此而言,迭代)。
相反,完成此操作的典型方法是创建一个小型包含文件,其中包含所有所需的#include。请参阅 Cory Petosky 的回复以获取说明。
警告:
虽然这可能会减少数百行代码,但您应该考虑到这些是“简单”的代码行。人们通常会浏览它们,这与与程序的真实逻辑相关的代码行不同。
此外,显式列出给定文件所需的各个包含内容可以提供一些自我文档,并且可以在需要时更轻松地重构代码。
编辑:这只是在;-)
有人刚刚问了这个问题 将所有项目标头放入一个文件中是个好主意吗?,并且响应似乎普遍同意我的观点,即对标头进行分组通常没有什么好处。
The #include pre-process directive being itself handled at in the same step as the macro evaluation, this would likely not work. I don't believe the pre-processing can be recursive. (or iterative, for that matter).
Instead, the typical way this is done is to create a small include file which includes all the desired #includes. See Cory Petosky's reponse for an illustration.
A word of caution:
While this may cut hundreds of line of code, you should consider that these are "easy" lines of code. One typically skims over them, unlike lines of codes associated with the true logic of the program.
Furthermore, explicitly listing the individual includes necessary for a given file provide a bit of self documentation, and make it easier for refactoring the code when needed.
Edit: This just in ;-)
Someone just asked this SO question Good idea to put all project headers into one file?, and the responses seem to generally agree with my take that there's typically little gain to be had from grouping headers.