Consider the two following programs:
program one
int main()
{
printf( "hello\n" );
}
program two
int main()
{
srand( 0 );
if( rand() ) {
printf( "hello\n" );
} else {
printf( "hello\n" );
}
}
Do they have the same observable behavior or not? According to C++ Standard (1.9/6) the observable behavior includes:
- reads and writes to
volatiledata - library I/O functions
Now srand() and rand() are likely not I/O functions (although I have no idea whether a given implementation uses some hardware noise source), but they modify program internal state. Do they manipulate volatile data? I don’t know. Calls to printf() are clearly I/O operations and sequences thereof are identical in both programs.
Do the two programs above have the same observable behavior? How do I know if two given programs have the same observable behavior?
As you say, that depends on whether
srand()andrand()have observable side effects. They shouldn’t; there can be no external noise source, since the sequence is required to be repeatable for a given seed, and there is no other reason to perform I/O or access volatile data.If the compiler is able to determine that they don’t (e.g. if they are defined inline in a header, or the linker is smart enough to perform extra optimisations), then it would be able to omit them; otherwise, it must assume that they do, and include them. In many implementations, these functions will be in a precompiled library, and the linker won’t be that smart, so you will end up calling the functions; however, a decent compiler should notice that both branches of the
ifare identical and omit the test.(UPDATE: as noted in the comments, the call to
rand()can also only be omitted if the compiler can determine that no future observable behaviour can depend on its side effects).In general, that’s a very difficult problem, and there will be some programs where it’s impossible to tell (for reasons similar to the Halting Problem). For programs as simple as this, you can simply list the observable operations and compare them; if the behaviour depends on the program’s input in a non-trivial way, then that soon gets very difficult to do.