将"定义宏"替换为空实现
Replace 'Define macro' with empty implementation
我通常使用 #define
宏来添加代码,这些代码将在编译为调试时而不是在编译为发布时出现在这里。例如:
#ifdef NDEBUG
# define LOG(msg) (void)msg
#else
# define LOG(msg) MyDebugLogger(msg)
#endif
取而代之的是,我正在考虑使用普通函数,只是没有为发布方法提供正文:
void MyDebugLogger(std::string const& msg);
在 MyDebugLogger 中.cpp:
void MyDebugLogger(std::string const& msg)
{
#ifdef NDEBUG
std::clog << msg << "n"; // Or whatever
#else
(void)msg;
#endif
}
我希望编译器将有能力去除调用并在 Release 中不增加额外的成本。我说的对吗?出于某种原因,这可能是一种不好的做法吗?
编辑:我的问题是:如果我像以前一样使用宏,我知道在发布模式下,可执行文件会更小更快,因为所有代码都已删除。如果我使用该功能,它会是一样的吗?因为编译器可能理解该函数不执行任何操作,也不是必需的。(或者它会添加一个额外的,甚至是小的,用于调用空函数)
实际上你会做与宏相同的操作:
void MyDebugLogger(std::string const& msg)
{
#ifdef NDEBUG
std::clog << msg << "n"; // Or whatever
#endif
}
你的示例应该可以工作,但稍作调整。在当前版本中,编译器只"看到"函数签名,并将发出对其符号的调用,稍后将通过链接器解析,因此它无法自行优化它。(链接时间优化可能会对此有所帮助,但这在很大程度上取决于您的设置,动态链接将使这变得不可能)。所以也许尝试这样的事情在标题中:
// Assuming you are using clang or gcc,
// but is required to not give an error by the standard and probably
// not even needed.
[[gnu::always_inline]]
void MyDebugLogger(std::string const& msg [[maybe_unused]])
{
#ifdef NDEBUG
MyDebugLoggerImplementation(msg);
#endif
}
然后在.cpp文件中实现它。这种方法的另一个好处是你方法需要使用 NDEBUG 编译记录器,而此方法为客户端代码提供了选择。
相关文章:
- 如何正确实现和访问运算符的各种自定义枚举器
- 根据C++标准的定义实现"is_similar"类型特征
- 如何实现自定义匹配器以检查 Catch2 中的对象相等性
- 它是否定义了哪些算法可以接受可变 lambda 的实现?
- C++:实现定义了可接受的物理源文件字符
- 未定义与未指定与实现定义的行为
- 如何从uint8_t的缓冲区读取带符号整数,而不调用未定义或实现定义的行为
- 在哪里查找 GCC 实现定义行为的实现?
- 高效的无符号到签名转换,避免实现定义的行为
- C++中是否有实现定义行为的完整列表
- char的实现定义是否会影响std::string
- 强制实现/定义函数声明
- 实现定义为使用保留向量而不调整其大小
- 实现定义的文件流同步 - 原因
- 为什么 1 << 31 在 C++14 中更改为实现定义?
- 是实现定义的unsigned short + int类型
- 实现定义的行为和将unicode读取到缓冲区
- 为什么name()函数返回的字符串是实现定义的
- main()的链接是由实现定义的,这意味着什么
- Visual Studio 2010 - 为什么字符串文本比较是C++中实现定义的行为