是不是;“未定义的行为”;真的允许任何事情发生吗? 当然,“未定义行为”的经典伪证是“鼻魔”——物理上不可能的,不管C和C++标准允许什么。 因为C和C++社区倾向于强调不可预定义的行为的不可预测性,以及当编译器遇到不确定的行为时,编译器被允许使程序做字面上的任何事情的想法,我认为标准对行为的行为没有任何限制。未定义的行为
但是:是不是;“未定义的行为”;真的允许任何事情发生吗? 当然,“未定义行为”的经典伪证是“鼻魔”——物理上不可能的,不管C和C++标准允许什么。 因为C和C++社区倾向于强调不可预定义的行为的不可预测性,以及当编译器遇到不确定的行为时,编译器被允许使程序做字面上的任何事情的想法,我认为标准对行为的行为没有任何限制。未定义的行为,c++,c,language-lawyer,undefined-behavior,C++,C,Language Lawyer,Undefined Behavior,但是: [C++14:defns.undefined]:[…]允许的未定义行为范围从完全忽略情况到结果不可预测,到在翻译或程序执行过程中以环境特有的记录方式(无论是否发出诊断消息)进行行为,终止转换或执行(发出诊断消息)。[……] 这实际上指定了一小部分可能的选项: 忽略这种情况——是的,标准继续说这将产生“不可预测的结果”,但这与编译器插入代码不同(我认为这是鼻魔的先决条件) 以环境特有的记录方式行事——这听起来相对温和。(我当然没有听说过任何记录在案的鼻恶魔案例。) 终止转换或执行——带有
[C++14:defns.undefined]:
[…]允许的未定义行为范围从完全忽略情况到结果不可预测,到在翻译或程序执行过程中以环境特有的记录方式(无论是否发出诊断消息)进行行为,终止转换或执行(发出诊断消息)。[……]
这实际上指定了一小部分可能的选项:
- 忽略这种情况——是的,标准继续说这将产生“不可预测的结果”,但这与编译器插入代码不同(我认为这是鼻魔的先决条件)
- 以环境特有的记录方式行事——这听起来相对温和。(我当然没有听说过任何记录在案的鼻恶魔案例。)
- 终止转换或执行——带有诊断,不少于。希望所有的UB都能表现得这么好
- 我原以为从最初的问题上看很清楚,我想对大多数人来说也是这样,但我还是要说清楚:我确实意识到“鼻魔”是在开玩笑
- 请不要写(其他)答案来解释UB允许平台特定的编译器优化,除非您还解释了它如何允许实现定义的行为不允许的优化
这个问题并不是为了讨论未定义行为的(de)优点,但它就是这样。无论如何,对于那些认为这是一个重要话题的人来说,这可能是一个额外的兴趣。是的,它允许任何事情发生。这张便条只是举例而已。定义非常清楚: 未定义的行为:本国际标准未规定要求的行为
常见的混淆点: 您应该理解,“无需求”还意味着实现是而不是必需的,以保持行为未定义或做一些奇怪/不确定的事情
完全由C++标准允许实现,以记录一些理智行为并相应地执行。1,如果编译器要求在已签名的溢出上进行缠绕,逻辑(Sealsith.)将指示您欢迎依赖于编译器上的行为。只是不要期望另一个编译器以同样的方式运行,如果它没有声明
1见鬼,它甚至可以记录一件事,做另一件事。那是愚蠢的,它可能会让你扔进垃圾箱,你为什么相信一个文档是你的编译器?-但它不是针对C++标准的。< /P> < P>在每个C和C++标准中,未定义行为的定义本质上是标准不要求发生什么。 是的,这意味着任何结果都是允许的。但没有需要发生的特定结果,也没有不需要发生的任何结果。无论您是否拥有一个编译器和库,该编译器和库始终生成一个特定的行为来响应未定义行为的特定实例,这都无关紧要—这种行为不是必需的,甚至在将来的编译器修复版本中也会改变,编译器将仍然是完全正确的,根据C和C++标准的每个版本。
如果您的主机系统以连接插入鼻孔的探头的形式提供硬件支持,则发生未定义的行为可能会导致不期望的鼻腔影响。挑剔:您没有引用标准
这些是生成C++标准草稿的源代码。这些来源不应被视为ISO出版物,也不应由它们产生的文件,除非正式通过C++工作组(ISO/IEC JTC1/SC22/WG21)。 解释:注释不符合ISO/IEC指令第2部分
文件正文中的注释和示例仅用于提供旨在帮助理解或使用文件的附加信息它们不应包含要求(“应”见3.3.1和表H.1)或被认为是使用本文件必不可少的任何信息,例如说明(强制性;见表H.1)、建议(“应”见3.3)。int i=INT_MAX;
i++;
printf("%d",i);
#include <stdio.h>
int main(void)
{
int ch = getchar();
if (ch < 74)
printf("Hey there!");
else
printf("%d",ch*ch*ch*ch*ch);
}
if(!spawn_of_satan)
printf("Random debug value: %i\n", *x); // oops, null pointer deference
nasal_angels();
else
nasal_demons();
if(!spawn_of_satan)
nasal_demons();
else
nasal_demons();
nasal_demons();
int * ptr = calculateAddress();
int i = *ptr;
int bar = 0;
int foo = (undefined behavior of some kind);
if (foo) {
f();
bar = 1;
}
if (!foo) {
g();
bar = 1;
}
assert(1 == bar);