На этот вопрос есть много отличных ответов, объясняющих, почему ошибка может проявляться только в сборке выпуска.
Общие причины ошибок в версии выпуска отсутствуют в режиме отладки
У меня есть более конкретный вопрос относительно неопределенного поведения.
Если программа всегда работает правильно в сборке Debug, но ведет себя по-разному в сборке выпуска (однако всегда ведет себя одинаково некорректно), может ли проблема быть связана с неопределенным поведением?
Можно быть из-за неопределенного поведения? Конечно. Это всегда из-за неопределенного поведения? Конечно, нет.
Вообразите это:
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();
...
Теперь этот пример совершенно абсурден, но что-то подобное часто встречается в многопоточных средах. В этом примере это то, что происходит:
shared_var
в local_var
shared_var
shared_var
в local_Var
Как вы можете видеть, в этом примере блокировка ввода / вывода вызвала определенное поведение между потоками, которое само было включено только в режиме отладки. Это также означает, что программа, работающая в режиме отладки, может вести себя иначе, чем при компиляции для выпуска.
Других решений пока нет …