使用预处理器宏取消定义函数

Undefining functions using preprocessor macros

本文关键字:取消 定义 函数 处理器 预处理      更新时间:2023-10-16

我有一个用C++编写的日志系统,上面写着这种类型的函数:

    void processMessages();
    void DEBUG_MSG(const std::string& appender,const char* msg, ...);
    void INFO_MSG(const std::string& appender,const char* msg, ...);
    void WARNING_MSG(const std::string& appender, const char* msg, ...);
    void ERROR_MSG(const std::string& appender, const char* msg, ...);
    void FATAL_MSG(const std::string& appender, const char* msg, ...);

我想通过C++中的宏禁用。我已经阅读了这个线程:使用宏禁用函数,但

#ifdef GLOG_SILENCE
        #define processMessages     (void)sizeof
        #define DEBUG_MSG           (void)sizeof
        #define INFO_MSG            (void)sizeof
        #define WARNING_MSG         (void)sizeof
        #define ERROR_MSG           (void)sizeof
        #define FATAL_MSG           (void)sizeof
#else //GLOG_SILENCE
        void processMessages();
        void DEBUG_MSG(const std::string& appender,const char* msg, ...);
        void INFO_MSG(const std::string& appender,const char* msg, ...);
        void WARNING_MSG(const std::string& appender, const char* msg, ...);
        void ERROR_MSG(const std::string& appender, const char* msg, ...);
        void FATAL_MSG(const std::string& appender, const char* msg, ...);
#endif //GLOG_SILENCE

无法正常工作。我不断收到以下错误:

在包含的文件中 ../src/test_core.cpp:2:

../src/test_Log.h: In member function ‘virtual void LogTestFixtureTest_defining_SILENCE_macro_avoids_write_and_processing_activity_from_log_Test::TestBody()’:
../src/test_Log.h:63: error: expected unqualified-id before ‘(’ token
../src/test_Log.h:63: error: expected primary-expression before ‘void’
../src/test_Log.h:63: error: expected ‘;’ before ‘sizeof’
../src/test_Log.h:64: error: expected unqualified-id before ‘(’ token
../src/test_Log.h:64: error: expected primary-expression before ‘void’
../src/test_Log.h:64: error: expected ‘;’ before ‘sizeof’

我怀疑问题与 Log 是一个类的事实有关,但我不知道该怎么做。一些帮助?

事实上,如果这些是成员函数,那么"静默"版本将扩展到废话:

log.(void)sizeof(stuff);

您可以定义一个不执行任何操作的成员函数,以及吞噬其参数的宏:

void nothing() {}
#define processMessages(...) nothing()

然后使用"静默"版本将给出有效的代码,这些代码应该编译为零:

log.nothing();

这样做的缺点是 (a) 您依赖编译器来内联空函数,而不是生成函数调用;(b) 在静默模式下编译时不检查参数的语法。

如果您的编译器支持可变参数宏,您可以简单地定义带有空替换的宏:

#ifdef GLOG_SILENCE
        #define processMessages(_1, _2, ...)
        #define DEBUG_MSG(_1, _2, ...)
        #define INFO_MSG(_1, _2, ...)
        #define WARNING_MSG(_1, _2, ...)
        #define ERROR_MSG(_1, _2, ...)
        #define FATAL_MSG(_1, _2, ...)
#else //GLOG_SILENCE
        void processMessages();
        void DEBUG_MSG(const std::string& appender,const char* msg, ...);
        void INFO_MSG(const std::string& appender,const char* msg, ...);
        void WARNING_MSG(const std::string& appender, const char* msg, ...);
        void ERROR_MSG(const std::string& appender, const char* msg, ...);
        void FATAL_MSG(const std::string& appender, const char* msg, ...);
#endif //GLOG_SILENCE

但是,仅当函数不是类或命名空间的成员,而是真正的全局函数时,这才有效。

我想建议你以不同的方式工作。只需声明接口 ILogger 之后在不同的记录器中实现它,例如

class ILogger{
 public:
        virtual void DEBUG_MSG(const std::string& appender,const char* msg, ...);
        virtual  void INFO_MSG(const std::string& appender,const char* msg, ...);
        virtual  void WARNING_MSG(const std::string& appender, const char* msg, ...);
        virtual  void ERROR_MSG(const std::string& appender, const char* msg, ...);
        virtual  void FATAL_MSG(const std::string& appender, const char* msg, ...);
        virtual ~ILogger(){}
};

对于文件记录器

class FileLogger : public ILogger{
 public:
        void DEBUG_MSG(const std::string& appender,const char* msg, ...){....}
        void INFO_MSG(const std::string& appender,const char* msg, ...){....}
        void WARNING_MSG(const std::string& appender, const char* msg, ...){....}
        void ERROR_MSG(const std::string& appender, const char* msg, ...){....}
        void FATAL_MSG(const std::string& appender, const char* msg, ...){....}
        virtual ~EmptyLogger(){}
};
and the empty logger like:

对于空记录器

class EmptyLogger : public ILogger{
 public:
        void DEBUG_MSG(const std::string& appender,const char* msg, ...){do nothing here}
        void INFO_MSG(const std::string& appender,const char* msg, ...){do nothing here}
        void WARNING_MSG(const std::string& appender, const char* msg, ...){do nothing here}
        void ERROR_MSG(const std::string& appender, const char* msg, ...){do nothing here}
        void FATAL_MSG(const std::string& appender, const char* msg, ...){do nothing here}
        virtual ~FileLogger(){}
};

之后,在您创建记录器的地方可能是工厂制作宏以生成不同类型的记录器。

class LoggerFactory{
public:
 static ILogger* getLogger(/*loggertype as argument*/){
   #ifdef GLOG_SILENCE
    /* create a normal logger*/
   #else
     return new EmptyLogger();
   #endif
 }
};