出口状态是可观察到的行为吗? [英] Is exit status observable behavior?

查看:113
本文介绍了出口状态是可观察到的行为吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C 2018 5.1.2.3 6说:

C 2018 5.1.2.3 6 says:

对符合标准的实现的最低要求是:

The least requirements on a conforming implementation are:

  • 严格根据抽象机的规则评估对易失对象的访问.

  • Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.

在程序终止时,写入文件的所有数据应与根据抽象语义执行程序所产生的结果相同.

At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.

交互式设备的输入和输出动态应按照7.21.3的规定进行.这些要求的目的是尽快显示未缓冲或行缓冲的输出,以确保在程序等待输入之前确实出现提示消息.

The input and output dynamics of interactive devices shall take place as specified in 7.21.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.

这是程序的可观察行为.

This is the observable behavior of the program.

表面上,这不包括程序的退出状态.

On the face of it, this does not include the exit status of the program.

关于exit(status),7.22.4.4 5说:

Regarding exit(status), 7.22.4.4 5 says:

最后,控制权返回到主机环境.如果status的值为零或EXIT_SUCCESS,则返回状态定义为成功终止的实现形式.如果status的值为EXIT_FAILURE,则返回实现定义的状态为不成功终止的形式.否则,返回的状态是实现定义的.

Finally, control is returned to the host environment. If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If the value of status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.

该标准没有告诉我们这是可观察到的行为的一部分.当然,将exit行为仅仅描述为C的抽象机是没有意义的.除非在环境中可观察到,否则将值返回给环境没有任何意义.因此,我的问题不是出口状态是否可观察到,而是C标准对可观察到的行为的定义是否存在缺陷.还是在适用标准的其他地方有文字?

The standard does not tell us this is part of the observable behavior. Of course, it makes no sense for this exit behavior to be a description purely of C’s abstract machine; returning a value to the environment has no meaning unless it is observable in the environment. So my question is not so much whether the exit status is observable as whether this is a defect in the C standard’s definition of observable behavior. Or is there text somewhere else in the standard that applies?

推荐答案

我认为可以将其组合在一起以查看答案是否属于§5.1.2.3.6的第一个要点:

I think it’s possible to piece this together to see the answer fall under the first bullet point of § 5.1.2.3.6:

严格根据以下内容评估对易失对象的访问 抽象机规则

Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine

进一步,第3.1节将访问"定义为:

Looking further, § 3.1 defines "access" as:

读取或修改对象的值

to read or modify the value of an object

和第3.15节将对象"定义为:

and § 3.15 defines an "object" as:

执行环境中数据存储区域的内容 可以代表值

region of data storage in the execution environment, the contents of which can represent values

奇怪的是,该标准未包含易失性对象"的定义.它确实包含第6.7.3.6节中具有挥发限定类型的对象"的定义:

The standard, curiously, contains no definition of "volatile object". It does contain a definition of "an object that has volatile-qualified type" in § 6.7.3.6:

具有volatile限定类型的对象可以通过以下方式进行修改 实现未知或具有其他未知副作用. 因此,引用此类对象的任何表达均应为 严格按照抽象机的规则进行评估,如 在5.1.2.3中进行了说明.

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3.

推断具有volatile限定类型的对象具有该限定性正是为了告知编译器实际上它是一个volatile对象,这似乎是不合理的,因此,我认为它不会扩展太多东西以至于无法使用该措辞是易失性对象"本身定义的基础,并将易失性对象定义为可以以实现方式未知的方式修改或具有其他未知副作用的对象.

It seems not unreasonable to infer that an object that has volatile-qualified type has that qualification precisely to inform the compiler that it is, in fact, a volatile object, so I don’t think it’s stretching things too far to use this wording as the basis of a definition for "volatile object" itself, and define a volatile object as an object which may be modified in ways unknown to the implementation or have other unknown side effects.

第5.1.2.3.2节对副作用"进行了如下定义:

§ 5.1.2.3.2 defines "side effect" as follows:

访问易失性对象,修改对象,修改文件或 调用执行这些操作中的任何一个的函数 效果,即执行环境状态的变化.

Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.

所以我认为我们可以将其组合如下:

So I think we can piece this together as follows:

  1. 返回要返回到主机环境的退出状态是 明显改变了执行环境的状态,因为 例如,收到后的执行环境 EXIT_SUCCESS必须处于与其他状态不同的状态 是否收到例如EXIT_FAILURE.返回出口 因此,根据§5.1.2.3.2

  1. Returning the exit status to be returned to the host environment is clearly a change in the state of the execution environment, as the execution environment after having received, for example, EXIT_SUCCESS, is necessarily in a different state that it would be had it received, for example, EXIT_FAILURE. Returning the exit status is therefore a side effect per § 5.1.2.3.2

exit()是执行此操作的函数,因此调用exit() 根据§5.1.2.3.2本身也有副作用.

exit() is a function that does this, so calling exit() is therefore itself also a side effect per § 5.1.2.3.2.

该标准显然没有提供给我们有关内部工作原理的详细信息 exit()exit()将使用哪种机制将该值返回给 主机环境,但是假设访问 不会涉及对象,因为对象是数据区域 存储在执行环境中,其内容可以表示 值,退出状态是一个值.

The standard obviously gives us no details of the inner workings of exit() or of what mechanism exit() will use to return that value to the host environment, but it’s nonsensical to suppose that accessing an object will not be involved, since objects are regions of data storage in the execution environment whose contents can represent values, and the exit status is a value.

由于我们不知道主机环境会做什么,如果有的话 响应状态变化(尤其是因为我们的程序 会在发生之前退出),但此访问权限未知 效果,因此访问的对象是易失性对象.

Since we don’t know what, if anything, the host environment will do in response to that change in state (not least because our program will have exited before it happens), this access has an unknown side effect, and the object accessed is therefore a volatile object.

由于调用exit()可以访问易失性对象,因此可以观察到 根据第5.1.2.3.6节的行为.

Since calling exit() accesses a volatile object, it is observable behavior per § 5.1.2.3.6.

这与对具有volatile限定类型的对象的常规理解是一致的,即,如果我们不能确定不会遗漏任何必需的副作用(因为可观察到的行为),则无法优化对此类对象的访问.如果这样做的话,正常的日常感)可能会受到影响.当然,在这种情况下,没有可见的volatile限定类型的对象,因为易失对象是exit()在内部访问的问题,并且exit()显然甚至不需要用C编写.易失性对象,第5.1.2.3节专门(三遍)指代易失性对象,而不是易失性限定类型的对象(第6.2.4.2节的脚注除外),这是标准易失性对象中的唯一位置被引用.)

This is consistent with the normal understanding of objects that have volatile-qualified types, namely that we can’t optimize away accesses to such objects if we cannot determine that no needed side effects will be omitted because the observable behavior (in the normal everyday sense) may be affected if we do. There is no visible object of volatile-qualified type in this case, of course, because the volatile object is question is accessed internally by exit(), and exit() obviously need not even be written in C. But there seems undoubtedly to be a volatile object, and § 5.1.2.3 refers specifically (three times) to volatile objects, and not to objects of volatile-qualified type (and other than a footnote to § 6.2.4.2, this is the only place in the standard volatile objects are referred to.)

最后,这似乎是使第5.1.2.3.6节易于理解的唯一读物,从直觉上讲,我们希望仅使用标准描述的功能,C程序的可观察到的行为"才是宽松的:

Finally, this seems to be the only reading that renders § 5.1.2.3.6 intelligible, as intuitively we’d expect the "observable behavior" of C programs using only the facilities described by the standard to be that which loosely:

  • 以一种在程序本身之外可见的方式更改内存;
  • 更改文件的内容(根据定义,这些内容在 程序本身);和
  • 影响与交互式设备的交互
  • Changes memory in a way that’s visible outside of the program itself;
  • Changes the contents of files (which are by definition visible outside of the program itself); and
  • Affects interactions with interactive devices

这实际上是第5.1.2.3.6节试图达到的目标.

which seems to be essentially what § 5.1.2.3.6 is trying to get at.

修改

在注释中似乎没有什么争议,这些注释显然围绕这样的思想,即退出状态可以在寄存器中传递,而寄存器不能是对象.这种异议(无双关语)可以轻易驳斥:

There seems to be some little controversy in the comments apparently centered around the ideas that the exit status may be passed in registers, and that registers cannot be objects. This objection (no pun intended) is trivially refutable:

  1. 对象可以用register存储类说明符声明,并且此类对象可以由左值指定;

  1. Objects can be declared with the register storage class specifier, and such objects can be designated by lvalues;

内存映射寄存器在嵌入式编程中非常普遍,提供了与寄存器可以是对象,可以具有地址以及可以由lvalues指定的寄存器一样清晰的演示.实际上,内存映射寄存器是volatile限定类型最常见的用途之一;

Memory-mapped registers, fairly ubiquitous in embedded programming, provide as clear a demonstration as any that registers can be objects, can have addresses, and can be designated by lvalues. Indeed, memory-mapped registers are one of the most common uses of volatile-qualified types;

mmap()表明,即使文件内容有时也可以具有地址并且可以是对象.

mmap() shows that even file contents can sometimes have addresses and be objects.

通常,认为对象只能驻留在核心存储器或DRAM芯片组中的位置或地址"只能指代DRAM或其他通常可能称为的任何东西"是错误的.内存"或"RAM".执行环境中能够存储值(包括寄存器)的 Any 组件可以是一个对象,可以有一个地址,并可以由一个左值指定,这就是为什么定义标准中的对象"是用这种故意宽泛的术语来表达的.

In general, it's a mistake to believe that objects can only reside in, or that "addresses" can only refer to, locations in core memory, or banks of DRAM chips, or anything else that one might conventionally refer to as "memory" or "RAM". Any component of the execution environment that's capable of storing a value, including registers, could be an object, could potentially have an address, and could potentially be designated by an lvalue, and this is why the definition of "object" in the standard is cast in such deliberately wide terms.

此外,第5.3.2.1.9节之类的内容在实际对象的值"和抽象语义所指定的[值]"之间作了一些区分,表明实际对象是存在的真实事物.正如第3.15节中对对象"的定义所阐明的那样,在与抽象机器不同的执行环境中,规范确实与之密切相关.在这样的实际对象上,直到直到调用标准库函数为止,一直保持与标准本身有关的立场似乎是站不住脚的,在这种情况下,所有这些关切都消失了,这些事项突然变成了"C之外".

Additionally, sections such as § 5.3.2.1.9 go to some lengths to draw a distinction between "values of the actual objects" and "[values] specified by the abstract semantics", indicating that actual objects are real things existing in the execution environment distinct from the abstract machine, and are things which the specification does indeed closely concern itself with, as the definition of "object" in § 3.15 makes clear. It seems untenable to maintain a position that the standard concerns itself with such actual objects up to and only up to the point at which a standard library function is invoked, at which point all such concerns evaporate and such matters suddenly become "outside C".

这篇关于出口状态是可观察到的行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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