-3

这个问题有很多很好的答案来解释为什么一个错误可能只在发布版本中表现出来。
调试模式下不存在发​​布版本中错误的常见原因
我有一个关于未定义行为的更具体的问题。

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

4

1 回答 1

2

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

想象一下:

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()
    • 发布中:调用 fprintf,导致线程 2 休眠
      • 现在线程 1 将旧值复制shared_varlocal_var
    • 在调试中:线程一覆盖shared_var
      • 现在线程 1 将新值复制shared_varlocal_Var

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

于 2012-10-20T22:06:31.333 回答