0
votes

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.

2

2 Answers

6
votes

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 when Test1.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.

3
votes

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:

g++ Test1.cpp Common.cpp  # to build Test1.exe
g++ Test2.cpp Common.cpp  # to build Test2.exe