是否“未定义的行为"真的允许*任何*发生吗? [英] Does "Undefined Behavior" really permit *anything* to happen?

查看:36
本文介绍了是否“未定义的行为"真的允许*任何*发生吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

未定义行为"的经典伪造示例当然是鼻魔"— 无论 C 和 C++ 标准允许什么,这在物理上都是不可能的.

The classic apocryphal example of "undefined behavior" is, of course, "nasal demons" — a physical impossibility, regardless of what the C and C++ standards permit.

因为 C 和 C++ 社区倾向于如此强调未定义行为的不可预测性,以及允许编译器在遇到未定义行为时使程序按字面意思做任何事情的想法,我曾假设标准对未定义的行为没有任何限制.

Because the C and C++ communities tend to put such an emphasis on the unpredictability of undefined behavior and the idea that the compiler is allowed to cause the program to do literally anything when undefined behavior is encountered, I had assumed that the standard puts no restrictions whatsoever on the behavior of, well, undefined behavior.

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

But the relevant quote in the C++ standard seems to be:

[C++14: defns.undefined]: [..] 允许的未定义行为范围从完全无视情况并产生不可预测的结果,到在翻译或以环境特征的文件化方式执行程序(有或没有发布诊断消息),以终止转换或执行(发布诊断消息).[..]

[C++14: defns.undefined]: [..] Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). [..]

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

This actually specifies a small set of possible options:

  • 忽略情况 -- 是的,标准继续说这将产生不可预测的结果",但这与编译器插入代码不同(我认为这是鼻恶魔的先决条件).
  • 以符合环境特征的记录方式行事 -- 这实际上听起来相对温和.(我当然没有听说过任何记录在案的鼻恶魔案例.)
  • 终止翻译或执行 -- 带有诊断功能,不少于.是不是所有的 UB 都会表现得这么好.
  • Ignoring the situation -- Yes, the standard goes on to say that this will have "unpredictable results", but that's not the same as the compiler inserting code (which I assume would be a prerequisite for, you know, nasal demons).
  • Behaving in a documented manner characteristic of the environment -- this actually sounds relatively benign. (I certainly haven't heard of any documented cases of nasal demons.)
  • Terminating translation or execution -- with a diagnostic, no less. Would that all UB would behave so nicely.

我假设在大多数情况下,编译器选择忽略未定义的行为;例如,在读取未初始化的内存时,插入任何代码以确保一致的行为可能是一种反优化.我认为陌生人类型的未定义行为(例如时间旅行") 属于第二类——但这需要记录此类行为,并且环境特征"需要被记录在案.(所以我猜鼻妖只能由地狱电脑产生?).

I assume that in most cases, compilers choose to ignore the undefined behavior; for example, when reading uninitialized memory, it would presumably be an anti-optimization to insert any code to ensure consistent behavior. I suppose that the stranger types of undefined behavior (such as "time travel") would fall under the second category--but this requires that such behaviors be documented and "characteristic of the environment" (so I guess nasal demons are only produced by infernal computers?).

我误解了定义吗?这些是否仅作为可能构成未定义行为的示例,而不是完整的选项列表?任何事情都可能发生"的说法是否正确?仅仅意味着无视情况的意外副作用?

Am I misunderstanding the definition? Are these intended as mere examples of what could constitute undefined behavior, rather than a comprehensive list of options? Is the claim that "anything can happen" meant merely as an unexpected side-effect of ignoring the situation?

澄清两点:

  • 我认为最初的问题很清楚,我认为对大多数人来说是这样,但无论如何我还是要说明一下:我确实意识到鼻恶魔"是半开玩笑的.
  • 请不要写一个(其他)答案来解释 UB 允许特定于平台的编译器优化,除非您解释它如何允许实现定义的优化行为不允许.
  • I thought it was clear from the original question, and I think to most people it was, but I'll spell it out anyway: I do realize that "nasal demons" is tongue-in-cheek.
  • Please do not write an(other) answer explaining that UB allows for platform-specific compiler optimizations, unless you also explain how it allows for optimizations that implementation-defined behavior wouldn't allow.

这个问题的目的不是作为讨论未定义行为的(de)优点的论坛,但这就是它变成的样子.在任何情况下,这个线程关于一个假设的 C 编译器没有未定义的行为可能会让那些认为这是一个重要话题的人更感兴趣.

This question was not intended as a forum for discussion about the (de)merits of undefined behavior, but that's sort of what it became. In any case, this thread about a hypothetical C-compiler with no undefined behavior may be of additional interest to those who think this is an important topic.

推荐答案

是的,它允许任何事情发生.笔记只是举例.定义很明确:

Yes, it permits anything to happen. The note is just giving examples. The definition is pretty clear:

未定义的行为:本国际标准没有强加任何要求的行为.

Undefined behavior: behavior for which this International Standard imposes no requirements.

<小时>

常见的混淆点:

您应该理解无要求"意味着实施不需要保持行为未定义或做一些奇怪/不确定的事情!

You should understand that "no requirement" also means means the implementation is NOT required to leave the behavior undefined or do something bizarre/nondeterministic!

C++ 标准完全允许实现来记录一些理智的行为并做出相应的行为.1因此,如果您的编译器声称对有符号溢出进行回绕,那么逻辑(理智?)欢迎您依赖在该编译器上的这种行为.只是不要指望另一个编译器以相同的方式运行,如果它没有声称.

The implementation is perfectly allowed by the C++ standard to document some sane behavior and behave accordingly.1 So, if your compiler claims to wrap around on signed overflow, logic (sanity?) would dictate that you're welcome to rely on that behavior on that compiler. Just don't expect another compiler to behave the same way if it doesn't claim to.

1哎呀,甚至允许记录一件事并做另一件事.那是愚蠢的,它可能会让你把它扔进垃圾桶——你为什么要相信一个文档对你撒谎的编译器?——但这并不违反 C++ 标准.

1Heck, it's even allowed to document one thing and do another. That'd be stupid, and it'd probably make you toss it into the trash—why would you trust a compiler whose documentation lies to you?—but it's not against the C++ standard.

这篇关于是否“未定义的行为"真的允许*任何*发生吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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