久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

通過易失性引用/指針訪問聲明的非易失性對象是

Does accessing a declared non-volatile object through a volatile reference/pointer confer volatile rules upon said accesses?(通過易失性引用/指針訪問聲明的非易失性對象是否賦予所述訪問易失性規則?) - IT屋-程序員
本文介紹了通過易失性引用/指針訪問聲明的非易失性對象是否賦予所述訪問易失性規則?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

這將是一篇很長的文章,為了將其語境化并提供盡可能多的信息,我必須瀏覽各種鏈接和引號 - 這通常是我們進入 C/C++ 標準兔子洞的唯一方法.如果您對這篇文章有更好的引用或任何其他改進,請告訴我.但先總結一下,你可以責怪@zwol 我發這個;-) 目的是從兩個命題中找出真相:

  • C 和(通過導入;見注釋)C++ 標準要求通過 volatile *volatile & 訪問必須引用最初聲明的對象volatile 為了有 volatile 語義?
  • 或者 正在通過 volatile 指針/引用訪問一個非 volatile 限定的對象易變?

無論哪種方式,如果(看起來)措辭與意圖相比有些含糊不清 - 我們能否在標準本身中明確說明?

這些相互排斥的解釋中的第一種更為普遍,這并非完全沒有根據.但是,我希望表明有大量合理懷疑"支持第二條 - 特別是當我們回到基本原理和工作組論文中的一些先前段落時.


公認的智慧:引用的對象本身必須聲明為volatile

昨天的熱門問題 易失性"的定義是否如此易變,或者 GCC 是否存在一些標準合規性問題? 是通過假設產生的volatile 引用將賦予非 volatile 引用對象 volatile 行為 - 但發現它沒有,或者在不同程度上和在不可預測的方式.

接受的答案最初得出結論,只有所指對象的聲明類型才重要.這個和大多數評論似乎都同意等效原則正在發揮作用,正如我們對 const 所熟知的:如果引用具有與引用對象相同的 cv 限定條件:

<塊引用>

那一段的關鍵詞是對象.volatile sig_atomic_t flag; 是一個 volatile 對象.*(volatile char *)foo 只是通過 volatile 限定的左值訪問,標準不要求它有任何特殊效果.– zwol

這種解釋似乎被廣泛接受,如對這個類似但希望不是重復的問題的回答所示:對指向非易失性對象的 volatile 指針行為的要求 但即使在那里也存在不確定性:在回答說不",然后說可能"!無論如何...讓我們檢查標準,看看'不'是基于什么.


標準說了什么......或沒有

C11、N1548、§6.7.3:雖然很明顯,訪問volatile 定義的對象是 UBconst 類型通過不共享所述限定符的指針...

<塊引用>

6 如果試圖通過使用具有非const 的左值來修改用const 限定類型定義的對象- 限定類型,行為未定義.如果嘗試通過使用具有非volatile限定類型的左值來引用volatile限定類型定義的對象,行為未定義.(133)

...標準似乎沒有明確提到相反的情況,即volatile.此外,在總結 volatile 及其上的操作時,它現在談論的是 具有 volatile 限定類型的對象:

<塊引用>

7 具有 volatile 限定類型的對象可能會以實現未知的方式進行修改或具有其他未知的副作用.因此,任何引用此類對象的表達式都應嚴格按照抽象機的規則進行評估,如 5.1.2.3 中所述.此外,在每個序列點,最后存儲在對象中的值應與抽象機規定的值一致,除非被前面提到的未知因素修改. (134) 什么構成對具有 volatile<的對象的訪問/code>-qualified 類型是實現定義的.

我們是否假設has"等同于被定義為"?或 可以有" 是指對象限定符和引用限定符的組合嗎?

一位評論者用這種措辭很好地總結了這個問題:

<塊引用>

n1548 §6.7.3 ?6 開始,標準使用短語用 volatile 限定類型定義的對象"來區分它與具有 volatile 限定類型的左值".不幸的是,這種對象定義為"與左值"的區別沒有繼續下去,然后標準使用具有 volatile 限定類型的對象",并說什么構成對具有 volatile 限定類型的對象的訪問是實現定義的"(為了清楚起見,可以說左值"或對象定義為").那好吧.– Dietrich Epp

同一部分的第 4 段似乎不太經常被引用,但很可能是相關的,我們將在下一部分中看到.


合理懷疑:是否是一個 volatile 指針/引用,旨在為其取消引用賦予 volatile 語義?

上述答案有一個評論,其中作者引用了委員會早先的聲明,該聲明對引用必須與所指對象相匹配"的想法表示懷疑:

<塊引用>

有趣的是,[C99 volatile 的基本原理] 中有一句話暗示委員會意為*(volatile T*)x 強制對 x 的訪問被視為 volatile;但標準的實際措辭并沒有達到這一點.– zwol

我們可以從前面提到的第二個線程中找到關于這一部分基本原理的更多信息:指向非易失性對象的指針的行為要求

<塊引用>

另一方面,這篇文章引自 6.7.國際標準的基本原理 3--編程語言--C:

<塊引用>

將值轉換為限定類型無效;資格(volatile, say) 對訪問沒有影響,因為它已經發生案發前.如果需要訪問非易失性對象使用 volatile 語義,該技術是將地址轉換為對象到適當的指向限定類型??的指針,然后取消引用那個指針.

philipxy

從 那個字節線程,我們被稱為 C99s6.7.3 p3 - 又名 C11 的 p4 - 以及這個分析:

<塊引用>

有問題的段落就在理由文件中的第 6.7.3.1 節之前.如果您還需要引用標準文檔本身,請引用 6.7.3 p3:

與限定類型關聯的屬性僅對左值表達式有意義.

表達式(volatile WHATEVER) non_volatile_object_identifier不是左值,因此volatile"限定符沒有意義.

反之,表達式* (volatile WHATEVER *) &non_volatile_object_identifier一個左值(它可以放在賦值語句的左側),所以volatile"限定符的屬性在這種情況下具有其預期的含義.

Tim Rentsch

非常支持這個想法的演示,特別是關于第一個鏈接的問題/www/docs/n1381.pdf" rel="noreferrer">WG 論文 N1381.這引入了附件 memset_s() 來做 OP 想要的 - 保證內存的非省略填充.在討論可能的實現時,它似乎支持這個想法 - 通過省略說明任何要求 - 使用 volatile 指針來改變非 volatile 對象應該 根據指針的限定符生成代碼,而不管引用對象的...

<塊引用>

  1. 獨立于平臺的secure-memset"解決方案:

void *secure_memset(void *v, int c , size_t n) {易失性無符號字符 *p = v;而 (n--) *p++ = c;返回 v;}

<塊引用>

這種方法將防止內存清理被優化掉,并且它應該適用于任何符合標準的平臺.

...并且注意編譯器不這樣做...

<塊引用>

最近注意到一些編譯器不總是遵守 volatile 限定符而違反了標準.


誰是對的?

那太累了.這里肯定有很大的解釋空間,這取決于您碰巧讀過哪些文件,哪些沒有讀過,以及您如何選擇解釋許多不夠具體的單詞.似乎很明顯有些不對勁:要么:

  • 理由和 N1381 措辭錯誤或隨意,或
  • 它們被明確地追溯無效...或
  • 該標準措辭錯誤或隨意.

我希望我們能做得比過去似乎圍繞這一點的所有含糊不清和猜測做得更好 - 并得到一個更確定的聲明.為此,非常歡迎專家提供任何進一步的來源和想法.

解決方案

通過易失性引用/指針訪問聲明的非易失性對象是否賦予所述訪問易失性規則?

volatile 在 C & 中并不意味著同樣的事情.C++.C++ 標準使通過 volatile 左值的訪問變得可觀察.[1] 它說它打算與 C 行為相同.這就是 C 基本原理中描述的行為.盡管如此,C 標準說對 volatile 聲明的對象的訪問是可觀察的.(請注意,通過非 volatile 左值訪問 volatile 聲明的對象是未定義的.)

然而. 有一份缺陷報告基本上已經獲得委員會的同意(盡管仍然開放),標準應該說,并且意圖一直是,并且實現總是反映,它重要的不是對象的波動性(根據標準),而是訪問(的左值)的波動性(根據基本原理).

C11 版本 1.10 的缺陷報告摘要日期:2016 年 4 月 DR 476 左值的易變語義 04/2016 Open

當然,關于可觀察行為的處理是依賴于實現的.

真的沒有任何歧義.只是人們不能相信 C 標準行為可能是它的樣子,因為那不是 volatile 之前的歷史用法(當地址文字左值是被視為易失性對象),如基本原理所預期的那樣,由編譯器在之前和之后實現,由 C++ 標準解釋和描述,在 DR 中更正.同樣,標準很清楚,因為它沒有說非易失性訪問是可觀察的,所以它們不是.(副作用"是用于定義評估偏序的術語.)

[1] 或者至少希望現在是這樣.來自 underscore_d 的評論:

<塊引用>

對于 C++,另見 P0612R0:NB 評論 CH2:易變的,本月通過了 清理 C++ 標準中關于易失性對象"的一些遺留問題,當真正通過易失性泛左值訪問時,它的意思是什么(大概/希望是 C 的意思).

This'll be a long one, as to contextualise it and provide as much info as I can, I must meander through various links and quotes - as is often the only way once we enter the C/C++ Standard Rabbit Hole. If you have better citations or any other improvements to this post, please let me know. But to summarise up front, you can blame @zwol for me posting this ;-) and the aim is to find the truth from among two propositions:

  • Do the C and (by import; see comments) C++ Standards require that accesses via volatile * or volatile & must refer to an object originally declared volatile in order to have volatile semantics?
  • Or is accessing a non-volatile-qualified object through a volatile pointer/reference sufficient/supposed to make said accesses behave as if the object was declared volatile?

And either way, if (as it seems) the wording is somewhat ambiguous compared to the intent - can we get that made clear in the Standards themselves?

The 1st of these mutually exclusive interpretations is more commonly held, and that's not entirely without basis. However, I hope to show that there's a significant amount of "reasonable doubt" in favour of the 2nd - especially when we go back to some prior passages in the Rationale and WG Papers.


Accepted wisdom: the referred object itself must have been declared volatile

Yesterday's popular question Is the definition of "volatile" this volatile, or is GCC having some standard compliancy problems? arose by assuming a volatile reference would confer volatile behaviour on a non-volatile referent - but finding that it did not, or did to varying degrees and in an unpredictable way.

The accepted answer initially concluded that only the declared type of the referent mattered. This and most comments seemed to agree that equivalent principles are in play as we know well for const: the behaviour would only be volatile (or defined at all) if the reference has the same cv-qualification as the referred object:

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

This interpretation appears to be quite widely held, as seen in the responses to this similar-but-hopefully-not-duplicate question: Requirements for behavior of pointer-to-volatile pointing to non-volatile object But there's uncertainty even there: right after the answer says 'no', it then says 'maybe'! Anyway...let's check the Standard to see what the 'no's are based on.


What the Standard says... or doesn't

C11, N1548, §6.7.3: Whereas it's clear that it's UB to access an object defined with volatile or const type via a pointer that doesn't share said qualifier...

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)

...the Standard doesn't seem to explicitly mention the opposite scenario, namely for volatile. Moreover, when summarising volatile and operations thereon, it now talks about an object that has volatile-qualified type:

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.

Are we to assume "has" is equivalent to "was defined with"? or can "has" refer to a combination of object and reference qualifiers?

A commenter summed up the issue with this sort of wording well:

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

Paragraph 4 of the same section seems to be less frequently quoted but might well be relevant, as we'll see in the next section.


Reasonable doubt: Is/Was a volatile pointer/reference intended to confer volatile semantics on its dereference?

The aforementioned answer has a comment wherein the author cites an earlier statement by the Committee that cast doubt on the 'reference must match referent' idea:

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

We can find a bit more info on this bit of the Rationale, from the 2nd aforementioned thread: 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.

philipxy

And from that Bytes thread, we're referred to C99 s6.7.3 p3 - a.k.a. C11's p4 - and this analysis:

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

There is a very specific demonstration supporting this idea, with specific regard to the 1st linked question, in WG Paper N1381. This introduced the Annexed memset_s() to do what that OP wanted - guarantee non-elided filling of memory. In discussing possible implementations, it seems to support the idea - by omitting to state any requirement - that using a volatile pointer to alter a non-volatile object should generate code based on the qualifier of the pointer, regardless of that of the referred object...

  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.

...and that compilers not doing this are on notice...

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


Who's right?

That was exhausting. There's certainly a lot of room for interpretation here, depending on which documents you happen to have read vs which not, and how you choose to interpret a lot of words that aren't specific enough. It seems clear that something is amiss: either:

  • the Rationale and N1381 are wrongly or haphazardly worded, or
  • they were specifically invalidated retroactively... or
  • the Standard is wrongly or haphazardly worded.

I'd hope that we can do better than all the ambiguity and speculation that seems to have surrounded this in the past - and get a more conclusive statement put on record. To that end, any further sources and thoughts from experts would be very welcome.

解決方案

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

volatile doesn't mean the same thing in C & C++. The C++ standard makes accesses through volatile lvalues observable. [1] It says that it intends this to be the same as C behaviour. And that is the behaviour described in the C Rationale. Nevertheless the C Standard says that accesses to a volatile-declared objects are observable. (Note that accessing a volatile-declared object via a non-volatile lvalue is undefined.)

However. There is a defect report which essentially has committee agreement (although still open) that the Standard should say, and that the intent has always been, and that implementations have always reflected, that it is not the volatility of an object that matters (per the Standard) but of the volatility of (the lvalue of) an access (per the Rationale).

Defect Report Summary for C11 Version 1.10 Date: April 2016 DR 476 volatile semantics for lvalues 04/2016 Open

Of course, what is done about observable behaviour is implementation-dependent.

There really isn't any ambiguity. It's just that people can't believe that the C Standard behaviour could be what it is, because that is not the historical usage pre-volatile (when address-literal lvalues were taken to be of volatile objects), as intended by the Rationale, as implemented by compilers before and since, as interpreted and described by the C++ Standard, as corrected in the DR. Similarly, the standard is clear in that it doesn't say that non-volatile accesses are observable, so they're not. (And "side effect" is a term used in defining the evaluation partial order.)

[1] Or at least hopefully it does now. From a comment from 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).

這篇關于通過易失性引用/指針訪問聲明的非易失性對象是否賦予所述訪問易失性規則?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

Difference between std::reference_wrapper and simple pointer?(std::reference_wrapper 和簡單指針的區別?)
Difference between const. pointer and reference?(常量之間的區別.指針和引用?)
How to access the contents of a vector from a pointer to the vector in C++?(c++ - 如何從指向向量的指針訪問向量的內容?)
Meaning of *amp; and **amp; in C++(*amp; 的含義和**amp;在 C++ 中)
Why can#39;t I do polymorphism with normal variables?(為什么我不能對普通變量進行多態?)
Dereferencing deleted pointers always result in an Access Violation?(取消引用已刪除的指針總是會導致訪問沖突?)
主站蜘蛛池模板: 精品国产乱码一区二区三区 | 欧美成人一区二区三区 | 日韩不卡一区二区 | 日本高清视频网站 | 黄色欧美大片 | 男人天堂网址 | 免费观看成人鲁鲁鲁鲁鲁视频 | 国产午夜精品一区二区三区四区 | 欧美一a一片一级一片 | 久久久www成人免费精品张筱雨 | 久久久高清 | 最新中文字幕在线 | 国产成人免费视频 | 看片一区 | 国产乱码精品1区2区3区 | 日本三级精品 | 美女视频黄的免费 | 毛片1| 最近日韩中文字幕 | 超碰免费在线 | 亚洲综合婷婷 | www.久久| 久久国产精品精品 | 羞羞涩涩在线观看 | www国产亚洲精品久久网站 | 欧美在线播放一区 | 伊人精品一区二区三区 | 一级一级毛片免费看 | www免费视频 | 日韩综合一区 | 精品国产欧美一区二区三区成人 | 久久青青| 久久精品亚洲欧美日韩精品中文字幕 | 在线观看精品视频网站 | 青青久久av北条麻妃海外网 | 香蕉久久久 | 伊人免费观看视频 | 国产精品久久久久国产a级 欧美日韩国产免费 | 精品欧美乱码久久久久久 | 中文日韩在线视频 | 久久久www成人免费精品张筱雨 |