[C, фортран] задача - отладочная печать изменяет результат
Задача почему это происходит _у тебя_? Или действительно про сферического коня в вакууме?
Задачу - когда от такого надо избавиться могу представить, но задачу - написать такое...
Ну например так:
или просто вызов какой-нибудь функции с сайд эффектом. Но это уж совсем идиотом надо быть =)
#ifdef DEBUG
#define print_debug(a, b) printf(a, b)
#else
#define print_debug(a, b)
#endif
...
print_debug("%d", i++)
...
или просто вызов какой-нибудь функции с сайд эффектом. Но это уж совсем идиотом надо быть =)
Да тыща вариантов. Проезд по памяти, который при наличии отладочных конструкций проходит по другому месту. Или вообще какой-нибудь эвристичекий оптимизационный алгоритм, который сам себя по таймауту снимает, тогда при отладочной печати он меньше успеет сделать 

print_debug("%d", i++)это не отладочная печать - она меняет значение переменной. Отладочная - просто что-то выводит
Отладочная - просто что-то выводитДа, а перед этим она считает то, что собирается выводить. Давай еще раз вернемся ко 2-3 постам?
Проезд по памяти, который при наличии отладочных конструкций проходит по другому местуЭто как?
print_debug("%d", CalculateZeroFieldsCount
на вид просто печатает. И ведь так сразу и не скажешь, что у невинной функции может быть сайд-эффект!
на вид просто печатает. И ведь так сразу и не скажешь, что у невинной функции может быть сайд-эффект!
Отладочная печать не должна менять значения переменных, по определению. Всякие сайд-эффекты - это очевидно, что так можно сделать
оптимизационный алгоритм, который сам себя по таймауту снимает, тогда при отладочной печати он меньше успеет сделатьЭто тема
Блиа, если врубание отладочной печати изменяет результат работы проги, значит, в проге глюк. По определению отладочной печати.
То есть твоя задача - придумать хитровылавливаемый глюк. Нет?
То есть твоя задача - придумать хитровылавливаемый глюк. Нет?
оптимизационный алгоритм, который сам себя по таймауту снимает, тогда при отладочной печати он меньше успеет сделать
А как ты добьёшься того, чтобы _без_ отладочной печати он всегда выдавал один и тот же результат?
Можно ещё проще - печатать отладочную инфу в лог-файл, после чего выводить слово Йух если перед завершением программы лог не пустой.
Можно ещё проще - печатать отладочную инфу в лог-файл, после чего выводить слово Йух если перед завершением программы лог не пустой.
Это как?
void g(int n) {
int x[10];
x[n] = 666;
//printf("blabla");
f(x[n]);
}
Сейчас f вызывается от 666, даже если n отрицательное, потому что память вверх по стеку некому запортить. А если раскоментировать printf, то может f вызваться от чего-то другого, потому что x[n] попадает во фрейм этого printf-а при некоторых (отрицательных) n.
Не обязательно так сложно... Я с такими эффектами сталкивался, и неоднократно, однако вызваны они были иным - ошибками, связанными с невыделением памяти, например...
что-то вроде подобного:
Такой код не всегда приводит в выбросу segmentation fault или аналогам, и служит источником глюков, аналогично - с чтением из уничтоженного объекта, например. Это наиболее частая ошибка.
Второе, что я как-то обнаружил, и что мне очень понравилось - уже изощрённее, правда связано с неправильно спроектированным алгоритмом (а не с кодированием, как в предыдущем примере). Специфично для x86. Связано с тем, что реально на сопроцессоре при работе с 8-ми байтным типом данных процессор оперирует 10-ти байтными числами, а преобразование 10->8 происходит в момент записи числа из регистров сопроцессора в оперативную память. Соответственно, если в одном случае, когда не было отладочной печати, переменные всё время лежали внутри сопроцессора, то при дополнительных операциях они запихиваются в оперативку, в результате чего происходит округление и изменение результата. При правильном алгоритме разница будет минимальной, но при неправильном - может разойтись очень и очень сильно.
что-то вроде подобного:
double mm[8];
...........
mm[8] = some_val;
.......
if(debug)
printf("%lf",something);
rz=mm[8];
Такой код не всегда приводит в выбросу segmentation fault или аналогам, и служит источником глюков, аналогично - с чтением из уничтоженного объекта, например. Это наиболее частая ошибка.
Второе, что я как-то обнаружил, и что мне очень понравилось - уже изощрённее, правда связано с неправильно спроектированным алгоритмом (а не с кодированием, как в предыдущем примере). Специфично для x86. Связано с тем, что реально на сопроцессоре при работе с 8-ми байтным типом данных процессор оперирует 10-ти байтными числами, а преобразование 10->8 происходит в момент записи числа из регистров сопроцессора в оперативную память. Соответственно, если в одном случае, когда не было отладочной печати, переменные всё время лежали внутри сопроцессора, то при дополнительных операциях они запихиваются в оперативку, в результате чего происходит округление и изменение результата. При правильном алгоритме разница будет минимальной, но при неправильном - может разойтись очень и очень сильно.
10->8О! Это вообще отдельный разговор, я уже как-то писал кажись, как мы распараллеливали один итерационный алгоритм на SSE, и из-за того что SSE регистры 64 битные приходилось делать в 10 раз больше итераций, чем если на 80 битных регистрах сопроцессора считать

при некоторых (отрицательных) nтак же нельзя. Это может привести к ошибке во время выполнения
double mm[8];так тоже нельзя
mm[8] = some_val
а вдруг у тебя именно так?
особенно, если параметр - не int, а char
- см. соседние поста про isalpha из ctype.h
ты лучше фрагмент своего кода покажи
особенно, если параметр - не int, а char
- см. соседние поста про isalpha из ctype.h ты лучше фрагмент своего кода покажи
Оставить комментарий
stm7868162
Написать на С (фортране) прогу, в которой появление отладочной печати изменяет результат.т.е. есть прога, которая что-то считает; добавили отладочную печать - результат изменился
Кто-нить встречался с такой задачей ?