gpt4 book ai didi

c++ - 通过 volatile 引用/指针访问声明的非 volatile 对象是否赋予所述访问 volatile 规则?

转载 作者:行者123 更新时间:2023-12-02 02:57:55 29 4
gpt4 key购买 nike

这将是一篇很长的文章,为了将其上下文化并提供尽可能多的信息,我必须仔细浏览各种链接和引号——这通常是我们进入 C/C++ 标准兔子洞的唯一方法。如果您对这篇文章有更好的引用或任何其他改进,请告诉我。但要提前总结,you can blame @zwol for me posting this ;-)目的是从两个命题中找出真理:

  • 执行 C 和(通过导入;见注释)C++ 标准要求通过 volatile * 访问或 volatile &必须引用最初声明的对象 volatile为了拥有volatile语义?
  • 正在访问非 volatile - 合格对象通过 volatile指针/引用足以/应该使所述访问表现得好像对象已声明 volatile ?

  • 无论哪种方式,如果(看起来)与意图相比,措辞有些含糊不清 - 我们能说清楚吗在标准本身?

    这些相互排斥的解释中的第一种更为普遍,这并非完全没有根据。但是,我希望表明有大量的“合理怀疑”支持第二条 - 特别是当我们回到基本原理和工作组论文中的一些先前段落时。

    公认的智慧:所引用的对象本身必须已声明 volatile
    昨天的热门问题 Is the definition of “volatile” this volatile, or is GCC having some standard compliancy problems?通过假设 volatile 出现引用将授予 volatilevolatile 上的行为所指 - 但发现它没有,或者在不同程度上以不可预测的方式这样做。

    接受的答案最初得出的结论是,只有所指对象的声明类型才重要。这一点和大多数评论似乎都同意等效原则正在发挥作用,正如我们对 const 所熟知的那样。 :行为只会是 volatile (或完全定义)如果引用与被引用对象具有相同的 cv 限定:

    The key word in that passage is object. volatile sig_atomic_t flag; is a volatile object. *(volatile char *)foo is merely an access through a volatile-qualified lvalue and the standard does not require that to have any special effects. – zwol



    这种解释似乎被广泛接受,如对这个类似但希望不重复的问题的回答所示: Requirements for behavior of pointer-to-volatile pointing to non-volatile object但即使在那里也存在不确定性:在答案说“不”之后,它接着说“可能”!无论如何...让我们检查标准,看看'不'是基于什么。

    标准说什么……或没有

    C11, N1548,第 6.7.3 节 :而很明显,访问对象是 UB 定义为 volatileconst通过不共享所述限定符的指针键入...

    6 If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.(133)



    ...标准似乎没有明确提到相反的情况,即 volatile .而且,总结时 volatile及其操作,它现在谈论一个对象 volatile - 合格类型:

    7 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. Furthermore, at every sequence point the value last stored in the object shall agree with that prescribed by the abstract machine, except as modified by the unknown factors mentioned previously.(134) What constitutes an access to an object that has volatile-qualified type is implementation-defined.



    我们是否假设“有”等同于“被定义为”?或 can "has"引用对象和引用限定符的组合?

    一位评论者用这种措辞很好地总结了这个问题:

    From n1548 §6.7.3 ¶6 the standard uses the phrase "object defined with a volatile-qualified type" to distinguish it from "lvalue with volatile-qualified type". It's unfortunate that this "object defined with" versus "lvalue" distinction does not carry forward, and the standard then uses "object that has volatile-qualified type", and says that "what constitutes access to an object that has volatile-qualified type is implementation-defined" (which could have said "lvalue" or "object defined with" for clarity). Oh well. – Dietrich Epp



    同一部分的第 4 段似乎不太经常被引用,但很可能是相关的,我们将在下一节中看到。

    合理怀疑:是/曾经是 volatile用于授予的指针/引用 volatile取消引用的语义?

    上述答案有一个评论,其中作者引用了委员会早先的声明,该声明对“引用必须与所指相匹配”的想法表示怀疑:

    Interestingly, there is one sentence in there [C99 Rationale for volatile] that implies that the committee meant for *(volatile T*)x to force that one access to x to be treated as volatile; but the actual wording of the standard does not achieve this. – zwol



    我们可以从前面提到的第二个线程中找到有关这一部分基本原理的更多信息: Requirements for behavior of pointer-to-volatile pointing to non-volatile object

    On the other hand, this post quotes from the 6.7.3 of the Rationale for International Standard--Programming Languages--C:

    A cast of a value to a qualified type has no effect; the qualification (volatile, say) can have no effect on the access since it has occurred prior to the case. If it is necessary to access a non-volatile object using volatile semantics, the technique is to cast the address of the object to the appropriate pointer-to-qualified type, then dereference that pointer.



    飞利浦

    来自 that Bytes thread ,我们指的是 C99 s6.7.3 p3 - 又名 C11 的 p4 - 和这个分析:

    The paragraph in question is just before section 6.7.3.1 in the rationale document. If you also need to quote from the standard document itself, cite 6.7.3 p3:

    The properties associated with qualified types are meaningful only for expressions that are lvalues.

    The expression (volatile WHATEVER) non_volatile_object_identifier is not an lvalue, hence the 'volatile' qualifier is meaningless.

    Conversely, the expression * (volatile WHATEVER *) & non_volatile_object_identifier is an lvalue (it may be placed on the left side of an assignment statement), so the property of the 'volatile' qualifier has its intended meaning in this case.

    Tim Rentsch



    WG Paper N1381 中有一个非常具体的演示支持这个想法,特别是关于第一个链接的问题。 .这里介绍了附件 memset_s()做那个 OP 想要的 - 保证非省略的内存填充。在讨论可能的实现时,它似乎支持这个想法 - 通过省略说明任何要求 - 使用 volatile更改非 volatile 的指针对象 应该根据指针的限定符生成代码,而不管引用的对象的...

    1. Platform-independent ' secure-memset' solution:

    void *secure_memset(void *v, int c , size_t n) {
    volatile unsigned char *p = v;
    while (n--) *p++ = c;
    return v;
    }

    This approach will prevent the clearing of memory from being optimized away, and it should work on any standard-compliant platform.



    ......并且不这样做的编译器会引起注意......

    There has been recent notice that some compilers violate the standard by not always respecting the volatile qualifier.



    谁是对的?

    那太累了。这里肯定有很大的解释空间,这取决于您碰巧读过哪些文件,哪些没有读过,以及您如何选择解释许多不够具体的单词。似乎很明显有些不对劲:要么:
  • 基本原理和 N1381 措辞错误或随意,或
  • 它们被明确地追溯无效...或
  • 该标准措辞错误或随意。

  • 我希望我们能做得比过去似乎围绕着这一点的所有含糊不清和猜测做得更好 - 并获得一份更具决定性的声明。为此,非常欢迎专家的任何进一步来源和想法。

    最佳答案

    Does accessing a declared non-volatile object through a volatile reference/pointer confer volatile rules upon said accesses?


    volatile在 C 和 C++ 中并不意味着同样的事情。 C++ 标准使通过 volatile 左值的访问变得可观察。 [1] 它说它打算与 C 行为相同。这就是 C 基本原理中描述的行为。尽管如此,C 标准说对 volatile 声明的对象的访问是可观察的。 (请注意,通过非 volatile 左值访问 volatile 声明的对象是未定义的。)

    然而。有一份缺陷报告基本上已经获得委员会同意(尽管仍然开放),标准应该说,并且意图一直是,并且实现总是反射(reflect),重要的不是对象的易变性(根据标准)但访问(的左值)的波动性(根据基本原理)。

    C11 版本 1.10 的缺陷报告摘要日期:2016 年 4 月 DR 476左值的 volatile 语义 04/2016 Open

    当然,对可观察行为所做的事情是依赖于实现的。

    真的没有任何歧义。只是人们无法相信 C 标准行为可能是它的样子,因为这不是历史用法 pre- volatile (本地址文字左值被视为 volatile 对象时),如基本原理所预期的那样,由编译器之前和之后实现,由 C++ 标准解释和描述,如 DR 中更正。同样,标准很清楚,因为它没有说非 volatile 访问是可观察的,所以它们不是。 (“副作用”是用于定义评估偏序的术语。)

    [1] 或者至少希望现在是这样。来自 underscore_d 的评论:

    For C++, see also P0612R0: NB comment CH 2: volatile, which was adopted this month to clean up some leftover talk about "volatile objects" in the C++ Standard, when really accesses through volatile glvalues are what it meant (as, presumably/hopefully, what C meant).

    关于c++ - 通过 volatile 引用/指针访问声明的非 volatile 对象是否赋予所述访问 volatile 规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38243501/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com