【问题标题】:C++ Can Undefined Behavior cause Debug and Release Builds to behave differently?C++ 未定义的行为会导致调试和发布版本的行为不同吗?
【发布时间】:2012-10-11 04:10:42
【问题描述】:

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

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

【问题讨论】:

  • 未定义的行为可能导致任何事情,所以是的。
  • 当然这可能是由于未定义的行为。但是这里的编码问题到底是什么?
  • 行为是未指定,因此它可能导致任何事情发生,甚至可能导致nasal demons
  • “可以有未定义的行为” -- 是的。
  • @Rabenholz:为什么重要?你不能对未定义的行为进行推理,因为它在定义上是未定义的。因此,您可能会在两台不同的机器上看到完全相同的 UB 结果,或者您可能会看到完全不同的结果。没关系,就 C++ 标准而言,允许未定义的行为代码做任何事情

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


【解决方案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()
    • 发布中:调用 fprintf,导致线程 2 休眠
      • 现在线程 1 将 shared_var 的旧值复制到 local_var
    • 调试中:线程一覆盖shared_var
      • 现在线程 1 将 shared_var 的新值复制到 local_Var

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-11
    • 2014-08-11
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多