问题标签 [observable-behavior]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
245 浏览

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

考虑以下两个程序:

节目一

方案二

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

  • 读取和写入volatile数据
  • 库 I/O 函数

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

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

0 投票
5 回答
754 浏览

c++ - 在 C++ 中打印空字符串可观察行为吗?

在 C++03 标准可观察行为 (1.9/6) 中包括对库 I/O 函数的调用。现在我有这个代码:

这是对库 I/O 函数的正式调用,但没有效果。

它是可观察的行为吗?允许编译器消除它吗?

0 投票
2 回答
370 浏览

c++ - 这种编译器优化不一致是否完全由未定义的行为解释?

在前几天我和几个同事的一次讨论中,我拼凑了一段 C++ 代码来说明内存访问冲突。

经过很长一段时间几乎完全使用具有垃圾收集功能的语言之后,我目前正在慢慢返回 C++,我想,我失去了触摸显示,因为我对我的短程序表现出的行为感到非常困惑。

有问题的代码是这样的:

我在 Ubuntu 15.04 上使用 GCC 4.9.2 编译它并-O2设置了编译器标志。我在运行它时的期望是,当我的评论表示为“通过未初始化的指针写入”的行被执行时,它会崩溃。

然而,与我的预期相反,程序成功运行到最后,产生了以下输出:

我用-O0标志重新编译了代码(以禁用所有优化)并再次运行程序。这一次,行为如我所料:

(好吧,差不多:我没想到指针会被初始化为 0。)基于这个观察,我推测当用-O2set 编译时,致命指令被优化掉了。这是有道理的,因为没有进一步的代码访问pa->value由违规行设置的之后,因此,大概编译器确定它的删除不会修改程序的可观察行为。

我多次复制了这一点,每次程序在没有优化的情况下编译时都会崩溃,而在使用-O2.

当我在's 正文pa->value的末尾添加一行输出 ,时,我的假设得到了进一步证实:f()

正如预期的那样,有了这条线,程序总是崩溃,不管它是用什么优化级别编译的。

如果到目前为止我的假设是正确的,这一切都是有道理的。但是,如果我将代码从正文f()直接移动到 ,我的理解有些中断main(),如下所示:

禁用优化后,该程序会崩溃,正如预期的那样。但是,使用-O2时,程序成功运行到最后并产生以下输出:

这对我来说毫无意义。

这个答案提到“取消引用尚未明确初始化的指针”,这正是我正在做的,作为 C++ 中未定义行为的来源之一。

main()那么,与 中的代码相比,优化影响中代码的方式的差异是否f()完全由我的程序包含 UB 的事实来解释,因此编译器在技术上可以自由地“发疯”,还是存在一些根本差异,我不知道main(),与其他例程中的代码相比,在优化代码的方式之间?