递归(无返回值仍然有效)

20 浏览
0 Comments

递归(无返回值仍然有效)

经典的“未定义行为”例子当然是“鼻妖”——这是一种物理上不可能的情况,无论C和C++标准允许什么。

由于C和C++社区往往非常强调未定义行为的不可预测性,并认为编译器在遇到未定义行为时可以导致程序做任何事情,我原以为标准对于未定义行为的行为没有任何限制。

但是,C++标准中的相关引用似乎是:

[C++14: defns.undefined]: [..] 可许可的未定义行为范围从完全忽略情况并产生不可预测结果,到在翻译或程序执行期间表现出环境特性的文件方式(无论是否发出诊断消息),到终止翻译或执行(并发出诊断消息)。

这实际上规定了一小组可能的选项:

- 忽略情况--是的,标准继续说这将产生“不可预测的结果”,但这与编译器插入代码(我认为这是一种先决条件,你知道,鼻妖)不同。

- 表现出环境特性的文件方式--这听起来相对无害。(我当然没有听说过任何关于鼻妖的文件案例。)

- 终止翻译或执行--而且还有诊断消息。要是所有未定义行为都能如此友好地行事就好了。

我认为在大多数情况下,编译器选择忽略未定义行为;例如,当读取未初始化的内存时,插入任何代码以确保一致的行为可能是一种反优化。我想奇怪的未定义行为类型(如“时间旅行”)将属于第二类--但这要求这些行为被记录下来并且“表现出环境特性”(所以我猜鼻妖只能由地狱般的计算机产生?)。

我是否误解了定义?这些是仅仅作为可能构成未定义行为的例子,而不是全面的选项列表吗?声称“任何事情都可能发生”仅仅意味着忽略情况的意外副作用吗?

两个小的澄清点:

- 我认为从原始问题中是清楚的,而且我认为对大多数人来说也是如此,但我还是要明确说明一下:我确实意识到“鼻妖”是玩笑话。

- 请不要写一个(另一个)解释UB允许特定平台的编译器优化的答案,除非您还解释了它如何允许实现定义行为不允许的优化。

0
0 Comments

【问题出现的原因】

问题的出现源于对C++标准中"Undefined behavior"(未定义行为)的理解。C++标准对未定义行为没有明确的要求,也不限制实现采取何种行为。因此,编译器可以选择定义一些合理的行为并相应地进行处理,但不要求不同的编译器在未定义行为上具有相同的行为。这导致了程序在不同编译器上可能产生不同的结果。

【解决方法】

对于这个问题,可以采取以下解决方法:

1. 理解未定义行为的含义和用途,避免依赖未定义行为编写代码。

2. 了解不同编译器的行为差异,不要期望不同编译器对未定义行为的处理方式相同。

3. 对于特定的平台或编译器,可以根据其文档中所定义的行为来依赖未定义行为,但要注意这种依赖性在其他平台或编译器上可能无效。

4. 在编写代码时,尽量避免使用未定义行为,以确保代码的可移植性和稳定性。

总结起来,虽然C++标准对未定义行为没有明确的要求,但程序员应该尽量避免依赖未定义行为,以确保代码的可移植性和稳定性。在特定平台或编译器上,可以根据其文档中所定义的行为来依赖未定义行为,但要注意不同平台或编译器的行为差异。

0