程序状态的任何变化是否构成可观察的行为?



考虑以下两个程序:

程序一个

int main()
{
   printf( "hellon" );
}

程序两个

int main()
{
   srand( 0 );
   if( rand() ) {
      printf( "hellon" );
   } else {
      printf( "hellon" );
   }
}

它们是否具有相同的可观察行为?根据c++标准(1.9/6),可观察的行为包括:

  • 读写volatile数据
  • 库I/O函数

现在srand()rand()可能不是I/O函数(尽管我不知道给定的实现是否使用了一些硬件噪声源),但它们修改了程序的内部状态。他们是否操纵volatile数据?我不知道。对printf()的调用显然是I/O操作,其序列在两个程序中是相同的。

上面的两个程序是否具有相同的可观察行为?我如何知道两个给定的程序是否具有相同的可观察行为?

上面的两个程序是否具有相同的可观察行为?

正如你所说,这取决于srand()rand()是否有可观察到的副作用。他们不应该;不能有外部噪声源,因为序列要求对于给定的种子是可重复的,并且没有其他原因执行I/O或访问易失性数据。

如果编译器能够确定它们没有(例如,如果它们在头文件中被内联定义,或者链接器足够聪明以执行额外的优化),那么它将能够忽略它们;否则,它必须假定它们存在,并包含它们。在许多实现中,这些函数将在预编译库中,并且链接器不会那么智能,因此您最终将调用这些函数;然而,一个体面的编译器应该注意到if的两个分支是相同的,并省略测试。

(更新:如注释所述,对rand()的调用也只能在编译器确定未来的可观察行为不能依赖于其副作用时才可以省略)

我如何知道两个给定的程序是否具有相同的可观察行为?

一般来说,这是一个非常困难的问题,并且会有一些程序无法判断(原因类似于停止问题)。对于像这样简单的程序,你可以简单地列出可观察操作并比较它们;如果行为以一种非平凡的方式依赖于程序的输入,那么很快就会变得非常困难。

相关内容

最新更新