这个问题有许多很好的答案,解释了为什么错误只能在发行版中表现出来。
发行版本中不存在的错误原因在调试模式中不存在
我对不确定的行为有一个更具体的问题。
如果程序在调试构建中似乎总是正确地工作,但是在发布构建中行为不同(但是,始终以相同的不正确方式行为),问题是否是由于不确定的行为引起的吗?
可以是由于不确定的行为吗?当然。由于行为不确定,它是总是吗?当然不是。
想象一下:
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 fastn");
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
- 现在线程1将
- 在调试中:线程一个覆盖
shared_var
- 现在线程1将
shared_var
的新值复制到local_Var
- 现在线程1将
- 发行版:fprintf被称为,导致线程2入睡
您可以看到,在此示例中,阻止I/O强迫线程之间的某些行为,这本身仅在调试模式下才启用。这也意味着,在调试中工作的程序的行为可能与释放时不同。