【问题标题】:Best way to omit string constants from Release build从 Release 构建中省略字符串常量的最佳方法
【发布时间】:2020-08-28 00:36:29
【问题描述】:

问题

从程序的发布版本中删除某些字符串常量的更好方法是什么?

问题

我正在开发一个程序,并使用std::clog 将各种调试输出输出到控制台,例如clog << "State change complete." << endl; 我注意到在我的发布版本中,这些字符串常量仍然显示在编译的可执行文件中。解决这个问题的最佳方法是什么?如果可以的话,我不想使用宏。

我尝试过/考虑过的事情

我考虑使用宏作为代码行的包装器(例如DEBUG(clog << "string"); 我尝试使用宏作为字符串常量的包装器(例如clog << DSTRING("State change complete.");),并考虑使用全局常量(不寒而栗)将代码包装在if 条件中,例如if (falseIfRelease) { ... }

我还考虑将命名空间中的常量存储在两个单独的文件中,一个用于调试构建,另一个用于发布,发布构建文件中的常量是空字符串。但这需要花费大量精力来编写简单的调试消息。不用说,我对这些选项不太满意。

【问题讨论】:

  • 大多数编译器都有一个预定义宏的列表。查看他们用于调试的宏列表,例如NDEBUG
  • 在我的商店,我们发布调试版本。这将使我们能够调试在代码中发现的问题,而不必担心调试和发布版本之间的差异。我们在编程到平台之前去除了调试信息。
  • @ThomasMatthews,我熟悉预定义的宏。这些将是我确定是否应该定义我的宏的 goto,但如果可能的话,我正在寻找其他解决方案。

标签: c++


【解决方案1】:

您可以在 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 的日志时,这会产生非常便宜的跳过调试级别日志消息,尤其是与 @987654330 结合使用时@。

【讨论】:

    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多