如果C ++调用共享库,是否仍会出现无限循环的不确定行为? [英] Is infinite loop still undefined behavior in C++ if it calls shared library?

查看:102
本文介绍了如果C ++调用共享库,是否仍会出现无限循环的不确定行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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






来自 http://en.cppreference.com/w/cpp / language / memory_model


在有效的C ++程序中,每个线程最终都会执行以下
之一: / p>


  • 终止

  • 调用I / O库函数

  • 读取或修改易失性对象

  • 执行原子操作或同步操作



没有执行
这些可观察到的行为,任何执行线程都无法永远执行。



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







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



for(;;)sofunc();



该函数可以执行任何类型的阻塞I / O或引发异常。



情况下,编译器是否假设循环具有某些可观察到的行为?

解决方案

在很多地方,标准为编译器提供了超出进行有用的优化所需的自由,但是它将为编译器提供将最小惊讶原则排除在外的方法。有关无限循环的规则的编写方式适合该类别。即使是无限的,执行一段代码所需的时间也不被视为需要编译器保留的副作用。这样的规则将允许编译器省略任何没有直接副作用的循环迭代,并且不修改其他地方使用的值。



标准但是,不仅如此。给定代码:

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

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



我个人并不认为使用规则表明
(如果编译器可以证明如果没有X为真,循环就不会终止,无论
是否有任何手段,它们
都可以将X视为真。但是,基于该原理的优化似乎很受欢迎。


It's said that infinite loop for(;;); is undefined behavior.


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

In a valid C++ program, every thread eventually does one of the following:

  • terminate
  • makes a call to an I/O library function
  • reads or modifies a volatile object
  • performs an atomic operation or a synchronization operation

No thread of execution can execute forever without performing any of these observable behaviors.

Note that it means that a program with endless recursion or endless loop (whether implemented as a for-statement or by looping goto or otherwise) has undefined behavior.


But what if it calls a function in shared library?

for(;;) sofunc();

The function could do any kind of blocking I/O, or throw exception.

In this case, does the compiler assume that the loop has some observable behaviors?

解决方案

There are a number of places where the language of the Standard gives compilers freedoms beyond what are required for useful optimizations, but which would instead provide compilers with ways to throw the Principle of Least Astonishment out the window. The way the rules about endless loops are written fits that category.

Most of the optimizations which would be facilitated by the rules about endless loops would be enabled by language which specified that the time required to execute a section of code, even if infinite, is not considered to be a side-effect that compilers are required to preserve. Such a rule would allow a compiler to omit any loop iterations which don't have any direct side-effects and don't modify values that are used elsewhere.

The Standard, however, goes beyond that. Given the code:

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

a compiler that could show that functionWithNoSideEffects would never have any defined side-effects and would never return 23 could replace the code for "foo" with "return 42;". Even if the purpose of the program was to test whether functionWithNoSideEffects would ever return 42 (in which case having the generated code return 42 whether the function does or not would be unhelpful) the Standard would not require compilers to generate code to actually test that unless the loop included some kind of "side-effect".

I'm not personally convinced that the value of having a rule that says that if compilers can show that a loop can't terminate without X being true, they may regard X as being true whether or not there's any means by which it could be. Optimizations based on that principle seem popular, however.

这篇关于如果C ++调用共享库,是否仍会出现无限循环的不确定行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆