考虑以下两个程序:
int main()
{
printf( "hello\n" );
}
int main()
{
srand( 0 );
if( rand() ) {
printf( "hello\n" );
} else {
printf( "hello\n" );
}
}
他们是否有相同的可观察行为?根据C ++标准(1.9 / 6),可观察的行为包括:
volatile
数据现在srand()
和rand()
可能不是I / O函数(虽然我不知道给定的实现是否使用某些硬件噪声源),但它们会修改程序内部状态。他们是否操纵volatile
数据?我不知道。对printf()
的调用显然是I / O操作,其序列在两个程序中都是相同的。
上述两个程序是否具有相同的可观察行为?我怎么知道两个给定的程序是否具有相同的可观察行为?
答案 0 :(得分:8)
上述两个程序是否具有相同的可观察行为?
正如您所说,这取决于srand()
和rand()
是否具有可观察到的副作用。他们不应该;没有外部噪声源,因为序列需要对给定的种子是可重复的,并且没有其他理由来执行I / O或访问易失性数据。
如果编译器能够确定它们没有(例如,如果它们是在头中内联定义的,或者链接器足够智能以执行额外的优化),那么它将能够省略它们;否则,它必须假设他们这样做,并包括它们。在许多实现中,这些函数将位于预编译库中,并且链接器不会那么智能,因此您最终将调用函数;但是,一个不错的编译器应该注意到if
的两个分支都是相同的并省略了测试。
(更新:如注释中所述,如果编译器可以确定未来的可观察行为不会取决于其副作用,则也只能省略对rand()
的调用。)
我如何知道两个给定的程序是否具有相同的可观察行为?
一般来说,这是一个非常棘手的问题,并且会有一些程序无法分辨(出于类似于停机问题的原因)。对于像这样简单的程序,您只需列出可观察的操作并进行比较;如果行为以非平凡的方式依赖于程序的输入,那么很快就会很难做到。