【问题标题】:Compile out code for release build in D在 D 中编译发布版本的代码
【发布时间】:2010-07-06 22:56:20
【问题描述】:

在 D (D2) 中是否有任何机制可以强制在发布构建期间编译代码?

在 C 中,你可能有类似的东西

#ifndef NDEBUG
/*Something that will only run in a debug build*/
#endif

我知道 D 有

debug(mymodule) {
   //Do something
}

但这需要用户为每个模块传递 -debug 才能启用它。

我正在寻找一种全局机制,该机制将始终在正常构建中运行代码,但在传递 -release 标志时将其编译出来。我知道一些内置程序有这种能力(例如断言),但是用户代码有什么办法也可以做到吗?

【问题讨论】:

  • 我认为您的部分问题是 debug-release 在 D 中彼此没有任何关系。-release 暗示您正在编译发布版本并且它禁用各种检查(例如断言)。 -debug 启用调试语句。因此,您可能会争辩说 D 中并没有真正的“调试模式”。您有发布模式和非发布模式,能够在任一模式下启用调试语句。我不认为-release 应该像-debug 那样真正改变你的代码语义,所以这可能就是你不能做你想做的事情的原因。
  • 我不打算更改发布版本的语义。我只是在寻找在非发布版本中添加额外检查、打印等的最佳方法,该版本将在开发过程中始终开启。我认为它可以让开发人员更快地追踪问题。额外的检查和警告可以提示他们应该在哪些模块上启用 -debug。
  • 我给出了答案,但不知怎的,我对此感到难过。我建议在开发时只使用-debug 和debug{ //... }。恕我直言,在开发时避免出错比在发布时更容易出错。
  • 好吧,正如-release 的文档所说:“编译发布版本,这意味着不为合约和断言生成代码。不会对系统和受信任的函数进行数组边界检查。”它不适用于启用或禁用合同和断言之外的用户代码。即使您打算做的只是打开或关闭一些自己的检查,无论好坏,这似乎都不是release 的目的。这就是debug 的用途,如果这对您来说不够细粒度,请使用-version。这有点令人困惑,但似乎就是这样。

标签: d


【解决方案1】:

有一个全局的调试概念。随便写:

debug {
    ... code ...
}

【讨论】:

  • 我知道一定有像这样简单的东西。 D 编程语言只提到了特定于模块的调试,所以我没有意识到还有一个全局调试。现在我可以使用 debug {...} 进行基本调试,使用 debug(mymodule) {...} 添加更详细的调试。
  • 没错。为遗漏道歉。我在这里代表你添加了一个勘误表:erdani.com/tdpl/errata
【解决方案2】:

dmd -release -version=dist module.d

version(dist) {} else {
    int i = 9;
}

我能想到的最好的。

[更新]

就个人而言,我认为上述答案是“不好的”。上述解决方案会在发布过程中引入过于复杂的逻辑,我认为这应该是直截了当且可预测的。我建议只使用-debugdebug{ //... }。即使你觉得你可能在编译时忘记添加调试标志——你只是在开发!——错误很便宜。导致发布的错误更严重。

【讨论】:

  • 它并不像我希望的那么理想,因为您需要记住指定 -version 标志,但是这些细节可能对构建系统中的最终用户隐藏,所以它'会的。
【解决方案3】:

如果没有找到更好的答案,这样的解决方法应该可以工作:bool debugMode() { bool res; assert(!!(res = true)); return res; }

【讨论】:

  • 这是断言中的赋值。在发布模式下,断言及其内容被编译出来。因此,分配只发生在非发布版本中。
  • OP 正在寻找编译时解决方案,而断言从未出现在 CTFE 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
相关资源
最近更新 更多