【问题标题】:Differences that may occur between Debug and Release builds? [closed]Debug 和 Release 版本之间可能出现的差异? [关闭]
【发布时间】:2012-05-21 15:29:00
【问题描述】:

我今天在一次采访中被要求列出调试和发布版本之间可能出现的四个差异。我想它们意味着行为上的差异,而不是诸如调试信息之类的差异。我只能说出两个:

  1. 由于某些函数未内联,调试构建通常要慢得多。
  2. 由于速度差异,在具有竞争条件的多线程程序中,这些竞争条件可能仅在两个构建中的一个中变得明显。

我还能说出哪些其他差异?

【问题讨论】:

  • 实际上性能差异通常是由于调试版本缺乏优化
  • …并且通常在调试版本中启用额外的检查。
  • 调试构建通常链接到不同版本的运行时。
  • 一些调试版本将空值分配给未初始化的指针。 stackoverflow.com/questions/186237/…

标签: c++


【解决方案1】:

以下是一些差异的摘要:http://msdn.microsoft.com/en-us/library/aa236698%28v=vs.60%29.aspx。它包括:

  • 堆布局(使用调试内存分配器)
  • 宏(包括断言语句,以及“#ifndef NDEBUG”中包含的任何内容,在某些情况下可能会有很大的不同——例如,我知道一些 boost 库在调试模式下编译时会向结构添加额外的字段,可用于执行完整性检查)
  • 优化(大部分在调试版本中被禁用)
  • 初始化和错误指针:未初始化的变量在您分配给它们之前具有未定义的状态;但在调试版本中,它们通常会被初始化为某个已知状态(例如全零或全 #CCCCCCC 等)。

【讨论】:

    【解决方案2】:

    除了你的两个答案,这里还有四个:

    1. _DEBUG vs NDEBUG
    2. 链接器在调试和发布期间使用不同的库
    3. 调试版本还会生成用于调试的符号
    4. 代码最终可能会被优化掉,因此,在某些情况下,您可能会在发布期间对某些构造函数的调用较少,这可能会导致一些令人讨厌的错误。这是一个例子:
    Object x(3);
    Object y;
    y = x;
    

    对比:

    Object x(3);
    Object y = x;
    

    【讨论】:

      【解决方案3】:

      另外一点是,许多库都启用了额外的调试检查。具有讽刺意味的是,这可能意味着代码在调试版本中有效,但在发布版本中无效:

      想象一个分配函数,它会在调试版本中清零内存,但在发布版本中由于性能原因不会清零。如果随后读取此变量的值而不进行初始化,则调试版本会看到一个明确定义的(零)值,而发布版本可以看到任何值。

      相反,调试构建检查当然可以捕获未定义的行为,例如通过检查对[] 的访问是否在定义的范围内。

      【讨论】:

      • 哦,对了。我怎么会忘记溢出检查?啊,该死的! :(
      猜你喜欢
      • 1970-01-01
      • 2019-11-30
      • 2012-11-20
      • 2023-01-11
      • 2018-06-28
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 2016-05-29
      相关资源
      最近更新 更多