可能重复:
未定义、未指定和实现定义的行为
我试图加深对 C++ 中未定义行为的理解。假设 C++ 编译器将有意检测某些未定义行为的情况 - 例如,在两个序列点之间修改变量两次:
x++ = 2;
一旦那个虚构的编译器可靠地检测到这种情况,它就会说将十个完全随机的机器指令发送到生成的机器代码中。
根据 C++ 标准,任何被归类为 UB 的地方都没有要求发生什么。所描述的虚构编译器是否符合 C++ 标准?
可能重复:
未定义、未指定和实现定义的行为
我试图加深对 C++ 中未定义行为的理解。假设 C++ 编译器将有意检测某些未定义行为的情况 - 例如,在两个序列点之间修改变量两次:
x++ = 2;
一旦那个虚构的编译器可靠地检测到这种情况,它就会说将十个完全随机的机器指令发送到生成的机器代码中。
根据 C++ 标准,任何被归类为 UB 的地方都没有要求发生什么。所描述的虚构编译器是否符合 C++ 标准?
是的。该标准没有强加任何要求,因此它可以为所欲为:
未定义的行为
行为,例如在使用错误程序结构或错误数据时可能出现的行为,本国际标准对此没有要求。
正如一个注释,这是未定义的行为,但它不一定是一个很好的例子。在 g++ 4.4.1 上,它将拒绝编译:
错误:需要左值作为赋值的左操作数
因为后增量的结果不是左值。
本质上,是的,当且仅当这 10 条指令同样可访问。考虑以下代码:
int main () {
if (false) {
int x = 0; x++ = 2;
}
std::cout << "Hello, world" << std::endl;
}
UB 可能在编译时被检测到,并且该特定分支的代码生成可能会导致无意义的代码。但是,非条件跳转必须跳过所有这些并直接越过结束}
(这个问题不是重复的,因为之前没有涵盖运行时UB的编译时检测)
特定的编译器(除非有错误)在遇到此类构造时总是具有相同的行为(绝对没有随机代码)(除非代码的上下文不同)。
在实践中,“未定义的行为”意味着“不同的编译器会以不同的方式处理事情”。
如果您想知道“您想象中的编译器是否仍符合 C++ 标准?” - 我认为答案是肯定的。
来自标准草案/http://www.kuzbass.ru:8086/docs/isocpp/intro.html/[1.3.12 ]
[注意:允许的未定义行为范围从完全忽略具有不可预测结果的情况,到在翻译或程序执行期间以环境特征的记录方式表现(有或没有发出诊断消息),到终止翻译或执行(发出诊断消息)。许多错误的程序结构不会产生未定义的行为;他们需要被诊断出来。]
绝对没有列出插入随机指令,并且很难争辩说“范围从”方面将包括决定插入随机指令作为所列行为之间连续体的任何位置。;-)