c++ - 从Release版本中省略字符串常量的最佳方法

标签 c++


从程序的发行版本中删除某些字符串常量的更好方法是什么?
问题
我正在开发一个程序,并使用std::clog将各种调试输出输出到控制台,例如clog << "State change complete." << endl;,我注意到在我的发行版中,这些字符串常量仍显示在已编译的可执行文件中。解决此问题的最佳方法是什么?如果可以,我不希望使用宏。
我尝试过/考虑过的事情
我已经考虑过使用宏作为代码行的包装器(例如DEBUG(clog << "string");,我曾尝试使用宏作为字符串常量(例如clog << DSTRING("State change complete.");)的包装器,并考虑过使用全局常量(shudder)来包装代码在if条件下,例如if (falseIfRelease) { ... }
我还考虑过将常量存储在命名空间中的两个单独文件中,一个用于调试版本,另一个用于发布版本,而发布版本文件中的常量为空字符串。但这需要花费很多精力来编写简单的调试消息。不用说,我对这些选项不是很满意。

最佳答案

您可以在C++ 17中使用此技巧:扩展为未完成的if()语句的宏:

#include <iostream>

// Returns true iff we are logging with LOG().
inline constexpr bool isLogging() noexcept
{
  return
#if defined(NDEBUG)
    false
#else
    true
#endif
    ;
}

// Evaluate to an unfinished std::clog expression, or nothing at all.
#define LOG() if constexpr(isLogging()) std::clog

int
main()
{
  LOG() << "DEMO: This is a conditional string.\n";
  std::cout << "DEMO: This is always here.\n";
  LOG() << "DEMO: Exiting.\n";
}
是的,它使用一个(或两个)宏,但是您还将如何创建半个语句?
使用-DNDEBUG进行编译,并且LOG() -started语句消失了:
$ clang++-9 -std=c++17 -s -o prog main.cc && strings prog |grep DEMO
DEMO: This is a conditional string.
DEMO: This is always here.
DEMO: Exiting.
$ clang++-9 -std=c++17 -s -o prog main.cc -DNDEBUG && strings prog |grep DEMO
DEMO: This is always here.
您可以使用任何宏或条件来决定isLoggable()的行为。
同样的技巧也适用于普通的非constexpr条件(但不会以这种方式将字符串保存在图像中)。您可以使宏LOG(level)并仅在发出level的日志时才有条件地评估表达式,这使得调试级别的日志消息非常便宜,尤其是与__builtin_expect()结合使用时。

关于c++ - 从Release版本中省略字符串常量的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63625894/

相关文章:

c++ - 增加 float 值

c++ - const char * 指向同一内存位置

c++用std::string读写结构数组到二进制文件

c++ - 有没有什么算法可以将简单的 Haxe 代码转换为 C/C++ 代码文件?

c++ - "virtual"关键字在 C++ 的基类中是可选的吗?

c++ - 如何更改 QDockWidget float 按钮的颜色

c++ - 应该弃用 std::list 吗?

c++ - 如何在头文件的结构中获取变量? C++

c++ - 用户提供的 std::allocator 特化

c++ - 使用类来维护几个常量变量是个好主意吗