Through my experience I bumped into some odd behaviors when using printf (or any other std out logging ) for debugging .
Behavior 1 :
One common scenario Is when using printf in multithreaded applications in order to find why certain bug(s) are occurring, and using printf suddenly "fixed" the bug(s) (ofc printfs where agressivelly called, resulting in a huge output).
In this scenario I consider that printf adds some delays so there might be some low priority threads that don't get CPU, so I start looking in that direction.
Another direction I look after the miracle printf fix is on synchronization, because I speculate that calls to printf, although multithreaded , are synchronized behind by the system, so the different threads with printf get synchronized between themselves by waiting for each other to finish writing to the I/O buffer.
Q1 : Are my two suppositions regarding the first scenario correct ?
Q2 : Are there any other directions I should take into consideration when such a scenarios occurs ?
Behavior 2 :
This scenario very rarely happens , but when bumped into it will make even senior developers question themselves, and I would really appreciate an explanation regarding this.
It goes something like this :
- code doesn't work ... (clean, compile , run)
- code still doesn't work , so you add a printf to see why (clean, compile, run)
- code starts working fine .... you remove the previously added printf (clean, compile, run)
- the code works fine now !!!!!!!!!! (scratch head, stare in disbelief ).
In practice I used this approach more then once this approach to fix the CPU may pe pegged bug more then once when it occurred : Android "cpu may be pegged" bug .
It actually worked so well, that it became a known "fix" (and if it didn't work from the first try, you just repeat the process until it was gone).
Please note that the code was properly cleaned it was never the problem of linking with older compiled objects.
One of the most popular speculations is the fact that the compiled code is different , for unknown reasons (do compilers have some random according to lines of a certain file including whitespaces ? ).
Q3 : What can be the cause this behavior (I'm open to speculations as well) ? Can a compiler generate different assembly although the code is the same ?
Please note that the projects I'm talking about are quite large, with multiple static libraries, so these behaviors aren't replicable on small code snippets (although I've heard of scenario 2 happening on a single-file program as well).