4

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

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

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

4

3 回答 3

7

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

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

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

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

相对:

Object x(3);
Object y = x;
于 2012-05-21T15:40:54.530 回答
1

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

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

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

于 2012-05-21T15:35:17.957 回答