Почему оператор журнала изменяет вывод программы?

Однажды во время интервью мне задали следующий вопрос, и я до сих пор не совсем ясно понял ответ. Мне было интересно, если бы кто-нибудь знал, где я мог бы узнать больше, поиск в Google не сильно помог:

Скажем, у вас есть программа, которую вы хотите протестировать. Вы добавляете один лог-оператор, и внезапно программа, которая выдает ожидаемый результат, перестает производить ожидаемый результат. Что могло случиться?

2 ответа

Ага. Я на самом деле это случилось.

Давайте рассмотрим программу с ошибкой, которая искажает стек. Если вы вводите журнал или оператор печати, вызов журнала может сместить стек достаточно, чтобы он изменил поведение.

Интересно подумать, как показать пример. Вероятно, проще всего сделать это с плохим форматом в printf...

ладно, в общих чертах хотя бы пример будет выглядеть так.

int parent(){ ... printf("%s\n", itoa(child()));

int child(){
    int num;
    scanf("%d%d", num);  /* notice the format; scanf is going to eat more of the
                           * stack than it should.
                           */
    return num;            /* but this return may unwind the stack successfully. */
}

Ваш случай произойдет, если вы вставите printf() как раз перед возвращением.

Ваша программа может иметь условия состязания между параллельными потоками, поэтому любое изменение времени может изменить поведение программы.

Обычно это наоборот, и это намного хуже (так называемый Heisenbug): ваша программа ведет себя неправильно, и вы хотите отладить ее, добавив вывод журнала. Но вывод журнала устраняет проблему, поэтому диагностику становится очень сложно.

Другие вопросы по тегам