Относительно препроцессора C ++ при использовании #define для условного исключения основной функции - PullRequest
0 голосов
/ 26 октября 2010

Вот ситуация: у меня есть три файла, Test1.cpp и Test2.cpp.Test1.cpp может быть скомпилирован как есть в отдельное приложение.Test1.cpp также содержит некоторые функции, которые я хотел бы повторно использовать в Test2.cpp.Я использую блок #ifndef #endif для условного исключения основной функции Test1.cpp, чтобы при компиляции Test2.cpp основная функция в Test2.cpp могла вызывать функции, определенные в Test1.cpp.Пример кода:

--------------------------------------------
//File: Test1.h
#include <iostream>
void do_something();
--------------------------------------------
//File: Test1.h
#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;
}
--------------------------------------

Вызов g ++ с Test1.cpp работает нормально и ведет себя, как и ожидалось, но вызов g ++ с Test2.cpp и Test1.cpp завершается ошибкой, поскольку main определяется несколько раз.Однако вызов g ++ с параметром -DFN_MAIN и двумя исходными файлами решает эту проблему.Есть ли способ обойти это?Я думаю, что эта проблема проистекает из моего неполного понимания препроцессора C ++.

Примечание. Моя мотивация заключается в том, чтобы уменьшить размер кода в проекте, который я выполняю.работа над.Фактический проект включает в себя как отдельную версию Test1.cpp, так и несколько других программ, которые используют функции из Test1.cpp.

Ответы [ 2 ]

5 голосов
/ 26 октября 2010

Препроцессор запускается последовательно через каждый исходный файл.Макросы, определенные в одном файле .cpp, не влияют на макросы, определенные в другом файле .cpp.

Один из вариантов - определить FN_MAIN в заголовке: тогда, когда Test1.cpp включает этот заголовок, макрос все равно будет определен.Тем не менее, я думаю, что лучше определить макрос в командной строке;это зависит от того, какой у вас конкретный вариант использования.

Другой вариант - переместить Test1.cpp main() в отдельный файл .cpp и создать с ним отдельный исполняемый файл.

2 голосов
/ 26 октября 2010

Для решения вашей проблемы таким образом вам следует использовать #include "Test1.cpp" в Test2.cpp вместо включения Test1.h, а затем вызывать только g ++ с Test2.cpp.Таким образом, вы будете компилировать только один модуль компиляции, состоящий из всех исходных текстов как Test1.cpp, так и Test2.cpp.

Однако - это довольно плохая идея, поэтому не делайте этого.

Вместо этого вы должны организовать свои служебные функции в отдельные файлы, скажем, сначала просто в один файл Common.cpp с заголовочным файлом Common.h, чтобы упростить задачу.Затем вы компилируете и связываете эти файлы с каждым исполняемым файлом, который собираетесь создать.Это правильный способ сделать это, намного проще понять и работать с ним, и использование нескольких исходных файлов не делает ваши приложения больше.

В вашем случае, если вы переместили ваши общие методы, скажем, в Common.cpp / h, тогда вы будете делать что-то вроде этого:

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