具有未定义行为的表达式是否从未实际执行过会导致程序错误? [英] Does an expression with undefined behaviour that is never actually executed make a program erroneous?

查看:148
本文介绍了具有未定义行为的表达式是否从未实际执行过会导致程序错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在关于未定义行为(UB)的许多讨论中,已经提出了观点,在任何在程序中具有UB的构造的程序中,仅存在做任何事情(包括没有什么)。我的问题是,这是否应该在那种意义上,即使在UB与代码的执行相关联的情况下,而在标准中规定的行为(否则)规定,不能执行(这可能是对程序的特定输入;它可能不能在编译时决定)。



更非正式地发音,UB的气味符合实现以决定整个程序发臭,并且拒绝正确地执行,即使对于其行为被完全良好定义的程序的部分。示例程序将是

  #include< iostream> 

int main()
{
int n = 0;
if(false)
n = n ++; //未定义的行为,如果它被执行,它不
std :: cout<< Hi there.\\\
;
}



为了清楚起见,我假设程序格式正确(因此,尤其是UB不与预处理相关联)。事实上,我愿意限制UB关联到评估,这显然不是编译时实体。我认为(重点是我的)


之前是一个非对称,传递,通过单个线程(1.10)执行的评估之间的明智的关系,其导致那些评估之间的部分顺序



操作数的值计算
运算符在运算符结果的值计算之前排序。如果对于标量对象的副作用与使用相同标量对象的值相对于...或值计算不相符,则该行为是未定义的。 p>

最后一句话中的主题副作用和价值计算是评估的实例,因为这是之前排序的关系的定义。



我假设在上述程序中,标准规定不发生评估,其中最终句子被满足(相对于彼此和所描述的种类不相称),并且因此程序不具有UB;这是不错的。



换句话说,我相信,我的标题的问题的答案是否定的。但是,我会感谢其他人对这个问题的(积极的)意见。



也许对那些主张肯定回答的人来说,另一个问题,



此网站上的一些相关指针:




解决方案


如果对标量对象的副作用相对于等无效


副作用是执行环境的状态的变化(1.9 / 12)。更改是一种更改,而不是一个表达式,如果评估,可能会产生更改。如果没有变化,没有副作用。



这并不意味着任何代码从来没有执行过UB-free(虽然我很确定大部分是)。标准中每个UB的出现需要单独检查。(详细的文字可能过于谨慎,见下文)。




一个合格的执行良好的程序的实现应该产生相同的可观察行为
作为可能执行的一个对应的抽象机的实例与同一个程序
和相同的输入。但是,如果任何这样的执行包含未定义的操作,则该国际
标准不要求执行该程序的实现与该输入(甚至
关于第一个未定义操作之前的操作)。


(强调我)


$ b b

据我所知,这是唯一的规范性引用,说明未定义的行为是什么意思:在程序执行中的未定义的操作。没有执行,没有UB。


In many discussions about undefined behavior (UB), the point of view has been put forward that in the mere presence in a program of any construct that has UB in a program mandates a conforming implementation to do just anything (including nothing at all). My question is whether this should be taken in that sense even in those cases where the UB is associated to the execution of code, while the behaviour (otherwise) specified in the standard stipulates that the code in question should not be executed (and this possibly for specific input to the program; it might not be decidable at compile time).

Phrased more informally, does the smell of UB mandate a conforming implementation to decide that the whole program stinks, and refuse to execute correctly even the parts of the program for which the behaviour is perfectly well defined. An example program would be

#include <iostream>

int main()
{
    int n = 0;
    if (false)
      n=n++;   // Undefined behaviour if it gets executed, which it doesn't
    std::cout << "Hi there.\n";
}

For clarity, I am assuming the program is well-formed (so in particular the UB is not associated to preprocessing). In fact I am willing to restrict to UB associated to "evaluations", which clearly are not compile-time entities. The definitions pertinent to the example given are, I think,(emphasis is mine):

Sequenced before is an asymmetric, transitive, pair-wise relation between evaluations executed by a single thread (1.10), which induces a partial order among those evaluations

The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either ... or a value computation using the value of the same scalar object, the behavior is undefined.

It is implicitly clear that the subjects in the final sentence, "side effect" and "value computation", are instances of "evaluation", since that is what the relation "sequenced before" is defined for.

I posit that in the above program, the standard stipulates that no evaluations occur for which the condition in the final sentence is satisfied (unsequenced relative to each other and of the described kind) and that therfore the program does not have UB; it is not erroneous.

In other words I am convinced that the answer to the question of my title is negative. However I would appreciate the (motivated) opinions of other people on this matter.

Maybe an additional question for those who advocate an affirmative answer, would that mandate that the proverbial reformatting of your hard drive might occur when an erroneous program is compiled?

Some related pointers on this site:

解决方案

If a side effect on a scalar object is unsequenced relative to etc

Side effects are changes in the state of the execution environment (1.9/12). A change is a change, not an expression that, if evaluated, would potentially produce a change. If there is no change, there is no side effect. If there is no side effect, then no side effect is unsequenced relative to anything else.

This does not mean that any code which is never executed is UB-free (though I'm pretty sure most of it is). Each occurrence of UB in the standard needs to be examined separately. (The stricken-out text is probably overly cautious; see below).

The standard also says that

A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input. However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).

(emphasis mine)

This, as far as I can tell, is the only normative reference that says what the phrase "undefined behavior" means: an undefined operation in a program execution. No execution, no UB.

这篇关于具有未定义行为的表达式是否从未实际执行过会导致程序错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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