如果它调用共享库,C ++中是无限循环还是未定义的行为?

据说for(;;);无限循环for(;;); 是未定义的行为。


从http://en.cppreference.com/w/cpp/language/memory_model

在一个有效的C ++程序中,每个线程最终会执行以下操作之一:

  • 终止
  • 调用I / O库函数
  • 读取或修改一个易失性对象
  • 执行原子操作或同步操作
  • 没有任何执行线程可以执行永远不执行任何这些可观察到的行为。

    请注意,这意味着具有无限递归或无限循环的程序(无论是作为for语句还是通过循环goto或其他方式实现)都具有未定义的行为。


    但是如果它在共享库中调用一个函数呢?

    for(;;) sofunc();

    该函数可以做任何类型的阻塞I / O,或抛出异常。

    在这种情况下,编译器是否假定循环具有一些可观察的行为?


    还有一些地方标准的语言给编译器的自由超越需要什么有用的优化,但是这反而会提供编译器的方法,来扔最小惊讶原则窗外。 有关无限循环的规则的写法适合该类别。

    其中大部分将由有关无限循环的规则来促进的优化将通过指定执行一段代码所需要的时间,即使是无限的,不认为是编译器都需要一个副作用语言启用保留。 这样的规则将允许编译器省略任何没有任何直接副作用的循环迭代,也不会修改其他地方使用的值。

    然而,标准超越了这个标准。 给定代码:

    int foo(void)
    {
      int x=0;
      do
      {
        x=functionWithNoSideEffects(x);
      } while(x != 23 && x != 42);
      return x;
    }
    

    一个编译器可以显示functionWithNoSideEffects永远不会有任何已定义的副作用并且永远不会返回23可以用“return 42;”代替“foo”的代码。 即使程序的目的是测试functionWithNoSideEffects是否会返回42(在这种情况下,生成的代码返回42,无论函数是否会无益),标准将不需要编译器生成代码来实际测试该代码,除非循环包括某种“副作用”。

    我不是个人认为,有一个规则是说,如果编译器可以证明一个循环离不开X是真正的终止价值,他们可能认为X为真是否有任何手段,它可能是。 然而,基于该原则的优化似乎很受欢迎。

    链接地址: http://www.djcxy.com/p/30725.html

    上一篇: Is infinite loop still undefined behavior in C++ if it calls shared library?

    下一篇: Why is a `fork()` call not optimized away in an infinite loop?