C ++ Undefined Behavior是否会导致Debug和Release Build的行为不同?

时间:2012-10-20 21:44:28

标签: c++ undefined-behavior release-mode debug-mode

这个问题有很多很好的答案,可以解释为什么bug只能在Release版本中表现出来 Common reasons for bugs in release version not present in debug mode
关于未定义的行为,我有一个更具体的问题。

如果程序总是在Debug构建中正常工作,但在发布版本中表现不同(但总是以相同的错误方式运行),问题可能是由于未定义的行为造成的吗?

1 个答案:

答案 0 :(得分:1)

可以是由于未定义的行为吗?当然。由于未定义的行为,总是吗?当然不是。

想象一下:

assert(scanf("%d", &n) == 1);

此行将在发布模式下被删除。它不是未定义的行为,但它肯定会使您的程序以不同的方式运行。

assert可能是一个明显的例子,但想想这个更复杂的情况:

#ifndef NDEBUG
# define DBG(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
#else
# define DBG(fmt, ...) ((void)0)
#endif

int shared_var;

static inline void do_something_fast(void)
{
    DBG("doing something fast\n");
    shared_var = something_fast();
}

并有线程1:

...
mutex_unlock();
local_var = shared_var;
...

和主题2:

...
mutex_lock();
do_something_fast();
...

现在这个例子是完全荒谬的,但是这些内容在多线程环境中很常见。在这个例子中,会发生这种情况:

  • 线程1:调用mutex_unlock,唤醒线程2并进入休眠状态
  • 主题2:调用do_something_fast()
    • 在release中:调用fprintf,导致线程2进入休眠状态
      • 现在,主题1会将shared_var的旧值复制到local_var
    • 调试中的
    • :第一个线程覆盖shared_var
      • 现在,主题1会将shared_var的新值复制到local_Var

正如您所看到的,在此示例中,阻塞I / O强制线程之间的某种行为,这本身仅在调试模式下启用。这也意味着在调试中工作的程序可能与编译发布时的行为不同。