У меня есть макрос, определенный в заголовке, функция, на которой основан макрос, также находится в том же заголовке.
Вот очень простой c пример, не точный код, но, надеюсь, он дает достаточно, чтобы проиллюстрировать проблему:
myMacro.h:
#ifndef MYMACRO_H
#define MYMACRO_H
#ifdef _DEBUG
bool myAssertFn(int test, char const* desc, char const* file, int line) {
if (test != 0) {
//Test passes, no action required
return true;
}
std::string msg;
if (desc != nullptr) {
msg += "\n Context: ";
msg += desc;
}
if (file != NULL) {
msg += "\n File: ";
msg += file;
}
if (line > 0) {
msg += "\n Line: ";
msg += std::to_string(line);
}
//Construct filename
time_t tClock = time(0);
char szTime[24];
tm tmNow;
//Get system time
localtime_s(&tmNow, &tClock);
//Assertion Log File, path and name
static const char* assertLogFile = "./ALF.log";
//Build time / date of day prefix
sprintf_s(szTime, sizeof(szTime), "%04d/%02d/%02d %02d:%02d:%02d "
, tmNow.tm_year + 1900, tmNow.tm_mon + 1, tmNow.tm_mday
, tmNow.tm_hour, tmNow.tm_min, tmNow.tm_sec);
//Does file exist?
std::ofstream logFile(assertLogFile, std::ios_base::app);
//Write the content to the file
logFile << szTime << msg.c_str() << std::endl;
return false;
}
//Macro
#define myAssert(test, desc)\
myAssertFn((test), (desc), __FILE__, __LINE__)
#else
#define myAssert(test, desc)\
(void)0
#endif
#endif
Целью этого макроса является включение отладочной информации и замена стандартной функции assert с дополнительным преимуществом: запись результатов в файл.
Проблема заключается в том, что при компиляции я получаю:
error C2065: 'test' : undeclared identifier
error C2065: 'desc' : undeclared identifier
Другие ошибки, когда макрос используется в исходном файле:
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2365: 'myAssertFn' : redefinition; previous definition was 'function' myAssert.h(37) : see declaration of 'myAssertFn'
error C2078: too many initializers
error C2143: syntax error : missing ';' before 'const'
В любой исходный файл, которому нужен этот макрос, я просто включаю заголовок и использую макрос следующим образом:
myAssert(ptr != NULL, "ptr != NULL");
Если тест возвращает 0, то описание будет записано в файл с датой, отметкой времени, имя файла и номер строки, в которой происходит ошибка.