[C, фортран] задача - отладочная печать изменяет результат

stm7868162

Написать на С (фортране) прогу, в которой появление отладочной печати изменяет результат.
т.е. есть прога, которая что-то считает; добавили отладочную печать - результат изменился
Кто-нить встречался с такой задачей ?

rosali

Задача почему это происходит _у тебя_? Или действительно про сферического коня в вакууме?

Dasar

Задачу - когда от такого надо избавиться могу представить, но задачу - написать такое...

bleyman

Ну например так:

#ifdef DEBUG
#define print_debug(a, b) printf(a, b)
#else
#define print_debug(a, b)
#endif
...
print_debug("%d", i++)
...

или просто вызов какой-нибудь функции с сайд эффектом. Но это уж совсем идиотом надо быть =)

rosali

Да тыща вариантов. Проезд по памяти, который при наличии отладочных конструкций проходит по другому месту. Или вообще какой-нибудь эвристичекий оптимизационный алгоритм, который сам себя по таймауту снимает, тогда при отладочной печати он меньше успеет сделать

stm7868162

print_debug("%d", i++)
это не отладочная печать - она меняет значение переменной. Отладочная - просто что-то выводит

rosali

Отладочная - просто что-то выводит
Да, а перед этим она считает то, что собирается выводить. Давай еще раз вернемся ко 2-3 постам?

stm7868162

Проезд по памяти, который при наличии отладочных конструкций проходит по другому месту
Это как?

bleyman

print_debug("%d", CalculateZeroFieldsCount
на вид просто печатает. И ведь так сразу и не скажешь, что у невинной функции может быть сайд-эффект!

stm7868162

Отладочная печать не должна менять значения переменных, по определению. Всякие сайд-эффекты - это очевидно, что так можно сделать

stm7868162

оптимизационный алгоритм, который сам себя по таймауту снимает, тогда при отладочной печати он меньше успеет сделать
Это тема

bleyman

Блиа, если врубание отладочной печати изменяет результат работы проги, значит, в проге глюк. По определению отладочной печати.
То есть твоя задача - придумать хитровылавливаемый глюк. Нет?

stm7868162

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

bleyman

А как ты добьёшься того, чтобы _без_ отладочной печати он всегда выдавал один и тот же результат?
Можно ещё проще - печатать отладочную инфу в лог-файл, после чего выводить слово Йух если перед завершением программы лог не пустой.

rosali

Это как?
 
void g(int n) {
int x[10];
x[n] = 666;
//printf("blabla");
f(x[n]);
}

Сейчас f вызывается от 666, даже если n отрицательное, потому что память вверх по стеку некому запортить. А если раскоментировать printf, то может f вызваться от чего-то другого, потому что x[n] попадает во фрейм этого printf-а при некоторых (отрицательных) n.

alexkravchuk

Не обязательно так сложно... Я с такими эффектами сталкивался, и неоднократно, однако вызваны они были иным - ошибками, связанными с невыделением памяти, например...
что-то вроде подобного:

double mm[8];
...........
mm[8] = some_val;
.......
if(debug)
printf("%lf",something);
rz=mm[8];

Такой код не всегда приводит в выбросу segmentation fault или аналогам, и служит источником глюков, аналогично - с чтением из уничтоженного объекта, например. Это наиболее частая ошибка.
Второе, что я как-то обнаружил, и что мне очень понравилось - уже изощрённее, правда связано с неправильно спроектированным алгоритмом (а не с кодированием, как в предыдущем примере). Специфично для x86. Связано с тем, что реально на сопроцессоре при работе с 8-ми байтным типом данных процессор оперирует 10-ти байтными числами, а преобразование 10->8 происходит в момент записи числа из регистров сопроцессора в оперативную память. Соответственно, если в одном случае, когда не было отладочной печати, переменные всё время лежали внутри сопроцессора, то при дополнительных операциях они запихиваются в оперативку, в результате чего происходит округление и изменение результата. При правильном алгоритме разница будет минимальной, но при неправильном - может разойтись очень и очень сильно.

rosali

10->8
О! Это вообще отдельный разговор, я уже как-то писал кажись, как мы распараллеливали один итерационный алгоритм на SSE, и из-за того что SSE регистры 64 битные приходилось делать в 10 раз больше итераций, чем если на 80 битных регистрах сопроцессора считать

stm7868162

при некоторых (отрицательных) n
так же нельзя. Это может привести к ошибке во время выполнения

stm7868162

double mm[8];
mm[8] = some_val
так тоже нельзя

yolki

а вдруг у тебя именно так?
особенно, если параметр - не int, а char - см. соседние поста про isalpha из ctype.h
ты лучше фрагмент своего кода покажи
Оставить комментарий
Имя или ник:
Комментарий: