关于 C++使用 #define 有条件地排除主函数时的预处理器
情况是这样的: 我有三个文件,Test1.cpp 和 Test2.cpp。 Test1.cpp 可以按原样编译成独立的应用程序。 Test1.cpp 还包含一些我想在 Test2.cpp 中重用的函数。我使用 #ifndef #endif 块有条件地排除 Test1.cpp 的 main 函数,这样当我编译 Test2.cpp 时,Test2.cpp 中的 main 函数将能够调用 Test1.cpp 中定义的函数。示例代码:
--------------------------------------------
//File: Test1.h
#include <iostream>
void do_something();
--------------------------------------------
//File: Test1.cpp
#include "Test1.h"
void do_something();
{
std::cout<<"Done"<<std::endl;
}
#ifndef FN_MAIN
int main()
{
do_something();
return 0;
}
#endif
--------------------------------------
//File: Test2.cpp
#define FN_MAIN
#include "Test1.h"
int main()
{
do_something();
return 0;
}
--------------------------------------
使用 Test1.cpp 调用 g++ 工作正常并且行为符合预期,但使用 Test2.cpp 和 Test1.cpp 调用 g++ 失败,因为 main 被定义了多次。但是,使用 -DFN_MAIN 和两个源文件调用 g++ 可以解决此问题。有什么办法可以解决这个问题吗?我认为这个问题是由于我对 C++ 预处理器的不完全理解造成的。
注意:我这样做的动机是减少我正在处理的项目的代码大小。实际项目包括 Test1.cpp 的独立版本和使用 Test1.cpp 中的函数的其他几个程序。
Here's the situation:
I have three files, Test1.cpp and Test2.cpp. Test1.cpp can be compiled as-is into a stand-alone application. Test1.cpp also contains some functions that I would like to re-use in Test2.cpp. I'm using an #ifndef #endif block to conditionally exclude the main function of Test1.cpp so that when I compile Test2.cpp, the main function in Test2.cpp will be able to call functions defined in Test1.cpp. Example code:
--------------------------------------------
//File: Test1.h
#include <iostream>
void do_something();
--------------------------------------------
//File: Test1.cpp
#include "Test1.h"
void do_something();
{
std::cout<<"Done"<<std::endl;
}
#ifndef FN_MAIN
int main()
{
do_something();
return 0;
}
#endif
--------------------------------------
//File: Test2.cpp
#define FN_MAIN
#include "Test1.h"
int main()
{
do_something();
return 0;
}
--------------------------------------
Calling g++ with Test1.cpp works fine and behaves as expected, but calling g++ with Test2.cpp and Test1.cpp fails because main gets defined multiple times. However, calling g++ with -DFN_MAIN and the two source files fixes this problem. Is there any way to get around this? I'm thinking that this problem is coming from my less-than-complete understanding of the C++ preprocessor.
Note: My motivation for doing this is to reduce the size of the code on the project that I'm working on. The actual project includes both a stand-alone version of Test1.cpp and several other programs that use functions from Test1.cpp.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
预处理器按顺序运行每个源文件。在一个 .cpp 文件中定义的宏不会影响在另一 .cpp 文件中定义的宏。
一种选择是在标头中定义
FN_MAIN
:然后当Test1.cpp
包含该标头时,宏仍将被定义。但是,我认为在命令行上定义宏可能更清晰;这取决于您的具体用例。另一种选择是将
Test1.cpp
main()
移动到单独的 .cpp 文件中,并用它构建单独的可执行文件。The preprocessor runs sequentially through each source file. Macros defined in one .cpp file do not affect macros defined in another .cpp file.
One option is to define
FN_MAIN
in the header: then whenTest1.cpp
includes that header the macro will still be defined. However, I think it's probably cleaner to define the macro on the command line; it depends on what your specific use case is though.Another option would be to move the
Test1.cpp
main()
into a separate .cpp file and build a separate executable with it.要以这种方式解决您的问题,您应该在 Test2.cpp 中使用
#include "Test1.cpp"
而不是包含 Test1.h,然后仅使用 Test2.cpp 调用 g++。这样,您将只编译一个由 Test1.cpp 和 Test2.cpp 中的所有源代码组成的编译单元。然而,这是一个非常糟糕的主意,所以不要这样做。
相反,您应该做的是将实用程序函数组织到单独的文件中,例如,最初只是在一个带有头文件 Common.h 的文件 Common.cpp 中,以使事情变得非常简单。然后,您编译这些文件并将其链接到您要制作的每个可执行文件中。这是正确的方法,它更容易理解和使用,并且使用多个源文件不会使您的应用程序变得更大。
就您而言,将常用方法移至 Common.cpp/h 中后,您将执行如下操作:
To solve your problem this way you should use
#include "Test1.cpp"
in Test2.cpp instead of including Test1.h and then only call g++ with Test2.cpp. That way you'll be compiling just one compilation unit consisting of all the source from both Test1.cpp and Test2.cpp.However - that's a pretty bad idea, so don't do that.
What you should do instead is organize your utility functions into individual files, say, initially just in one single file Common.cpp with header file Common.h to keep things really simple. Then you compile and link those files into each executable you're going to make. That's the right way to do it, it's much easier to understand and work with, and using several source-files doesn't make you apps any bigger.
In your case, having moved your common methods into say Common.cpp/h, you'll then do something like this: