【问题标题】:Is a program well defined before the line that causes undefined behavior? [duplicate]程序是否在导致未定义行为的行之前定义良好? [复制]
【发布时间】:2018-09-10 09:18:38
【问题描述】:

考虑这段代码:

int main()
{
    printf("Hello World!\n");
    int i;
    i = i++ + ++i; // UB
}

此代码是否保证打印“Hello World!”?最后一行调用了未定义的行为,但这会使整个程序无效吗?

我找到了this,但这个问题是关于 C++ 的。这是关于C的。

它不是 Undefined behavior and sequence points 的重复,因为它是 C++。答案可能相同也可能不同,但这个问题是关于 C 的。

【问题讨论】:

  • 我想我在某处读到了一个程序,其行导致未定义行为实际上是一个具有未定义行为的程序。根据编译器优化,奇怪的事情可能会在所述行之前发生。
  • @kabanus:这与看起来的标准有关。编译器优化超出了标准。如此相关的是最多提供序列点的抽象机器。然而,除了这些人工程序之外,这个问题对于生产代码没有多大意义。
  • @toohonestforthissite 我的意思是编译器可以做任何它喜欢的事情,但我明白你的意思。
  • @melpomene 我添加了A C specific answer that also covers C++,所以现在这是一个可靠的副本。

标签: c undefined-behavior


【解决方案1】:

来自 C 标准 (3.4.3):

未定义的行为

行为,在使用不可移植或错误的程序结构或错误数据时, 本国际标准对此没有要求

后跟:

注意 可能的未定义行为包括完全无视情况和不可预测的情况 结果,在翻译或程序执行期间以文件的方式表现 环境(无论是否发出诊断消息),终止翻译或 执行(发出诊断消息)。

这意味着该标准不对整个程序的行为施加任何保证 - 包括“早期”操作。

但是,特定的实现可能会为某些未定义行为的实例添加某些保证(例如,请参阅编译器文档)。并且in practice,许多实现的行为方式大部分都与您描述的方式相同。但是,优化往往使这一点难以保证。另外,compilers sometimes eliminate entire branches if they contain undefined behavior.

【讨论】:

  • 这里有一些实际发生的例子:blog.regehr.org/archives/232
  • @melpomene:适合在特定目标平台上进行低级编程的高质量实现应该允许易失性访问触发此类访问在该平台上可能产生的任何操作的可能性。如果一个实现永远不会用于定义特定易失性访问行为的平台上的低级编程,例如触发信号,然后在易失性访问中优化未经检查的除法将是合适的。对于声称适用于任意平台的实现,这样的假设似乎很狡猾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 2022-07-19
相关资源
最近更新 更多