Date: Fri, 12 Feb 2021 09:45:48 -0500
On Thu, Feb 11, 2021 at 7:29 PM Paul M. Bendixen via SG14 <
sg14_at_[hidden]> wrote:
> Ok so I tried
> This is absolutely the first draft of a draft, or what i like to call
> the braindump edition. Formatting is horrible and wording could
> probably also be improved.
> Please let me know what you think and where it could be improved,
> especially if there are things I have omitted.
>
Besides a paper number, it also needs *your email address* for people to
send feedback.
The "Introduction" should be massively tersened:
*C++20 deprecated many functionalities of `volatile`, due to JF
Bastien's P1152R4 [Bastien, 2019]. The rationale was to prevent programmers
misunderstanding the meaning of `volatile` in threading code [Bastien,
2018]. While this rationale is sound, the deprecation of the compound
assignment operators for `volatile` caused some response from the embedded
community [Ooijen, 2020]. We propose to restore the compound assignment
operators.*
(Even simple refactorings like replacing "It is the hope of the author
that" with "It is the author's hope that" with "It is my hope that" with "I
hope that" can lighten the load. But in this case, I don't even think it
makes sense to say "I hope we can reach a compromise position" — compromise
for the sake of compromise is never the goal! The goal is to get into
whatever state satisfies your technical needs.)
sg14_at_[hidden]> wrote:
> Ok so I tried
> This is absolutely the first draft of a draft, or what i like to call
> the braindump edition. Formatting is horrible and wording could
> probably also be improved.
> Please let me know what you think and where it could be improved,
> especially if there are things I have omitted.
>
Besides a paper number, it also needs *your email address* for people to
send feedback.
The "Introduction" should be massively tersened:
*C++20 deprecated many functionalities of `volatile`, due to JF
Bastien's P1152R4 [Bastien, 2019]. The rationale was to prevent programmers
misunderstanding the meaning of `volatile` in threading code [Bastien,
2018]. While this rationale is sound, the deprecation of the compound
assignment operators for `volatile` caused some response from the embedded
community [Ooijen, 2020]. We propose to restore the compound assignment
operators.*
(Even simple refactorings like replacing "It is the hope of the author
that" with "It is the author's hope that" with "It is my hope that" with "I
hope that" can lighten the load. But in this case, I don't even think it
makes sense to say "I hope we can reach a compromise position" — compromise
for the sake of compromise is never the goal! The goal is to get into
whatever state satisfies your technical needs.)
--- > This is further amplified by the fact that vendors may supply macros for setting or clearing bits... If vendors actually do use `|=` and `&=` for setting and clearing bits, then just say > Vendors provide macros that use `|=` and `&=` on volatile objects. For example: > - RabbitFrog RTOS has a macro `FOO_SET_FLAG(y) (mm_flags[y >> 4]) |= (1<<(y & 0xF))` > - FrogRabbit RTOS has a macro `BAR_SET_MEM(x, y) *(volatile int*)y &= x` You definitely need examples, because the null hypothesis here is that people *don't* do this. --- > The argument against compound operations on volatile variables is that it leads the programmer to believe that the operation itself becomes compounded and therefore atomic. This is of course false (even though architectures where this is the case could be imagined). FWIW, my understanding is that the operation itself *is* frequently atomic, or at least divvied up differently from the non-volatile version. For example, on x86-64 Clang: https://godbolt.org/z/q5bn5K Non-volatile &= produces a load, modify-in-register, and store. Volatile &= produces a modify-in-memory, followed by a load (if the final value is needed by the expression). Vice-versa, sometimes the compiler enforces that volatile reads/writes are always done at the size of the data type (e.g. it is forbidden to access the low-order byte of a `volatile int` via a byte-sized load instruction), which can lead to more codegen than the non-volatile version. https://godbolt.org/z/sxx1aG > Now since there must always be a read, modify, write cycle it is possible that an interrupt would happen in between the read and the write, however most code that uses this idiom needs to take care of this by being right by construction i.e. not bit-twiddeling variables that are used in the interrupt service routines (ISRs). While there is probably some code found in the wild where this would indicate a problem, since this is so common in all these cases the construct would only be replaced by the equivalent non-compound statement, giving no benefit at all. Your use of the passive voice in the last sentence hurts you. "Would only be replaced" by whom?— the compiler, or the human programmer? If the human programmer is supposed to replace `x &= y` with `x = x & y` in order to avoid ISR/multithreading bugs, then *good*, that's exactly what C++20 wants them to do. IOW, I don't understand the thrust of this paragraph. ---- > Table 1: Occurrences of compound operations on variables typically associated with volatile The caption of this table doesn't match the description in the English text. These aren't occurrences of compound assignments on *typically volatile variables* — they're literally just all the compound assignments in the entire program! Most of these assignments probably don't involve volatile variables at all. > but the usage of this idiom also prevents adopters of C++ to use the C libraries provided with their toolchains I would like to see evidence of this. For example, you could provide a short "hello world"-style program (using some C library provided with your toolchain) and point to the line that would be deprecated in C++20. ---- > The simplest possible change that could possibly work would be to remove the text added to paragraph [expr.ass] point 6 as this would allow compound statements on volatile varaiables. Nit: "varaiables". I would like to see the specific wording proposal here, formatted similarly to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2266r0.html#wording if possible. IIUC, it's this: A simple *An* assignment whose left operand is of a volatile-qualified type is deprecated ([depr.volatile.type] <http://eel.is/c++draft/depr.volatile.type>) unless the (possibly parenthesized) assignment is a discarded-value expression or an unevaluated operand. <http://eel.is/c++draft/expr.ass#5.sentence-1> The behavior of an expression of the form E1 *op*= E2 is equivalent to E1 = E1 *op* E2 except that E1 is evaluated only once. <http://eel.is/c++draft/expr.ass#6.sentence-1> Such expressions are deprecated if E1 has volatile-qualified type; see [depr.volatile.type] <http://eel.is/c++draft/depr.volatile.type>. <http://eel.is/c++draft/expr.ass#6.sentence-2> For += and -=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type. <http://eel.is/c++draft/expr.ass#6.sentence-3> In all other cases, E1 shall have arithmetic type. <http://eel.is/c++draft/expr.ass#6.sentence-4> ---- Personally, I'd like to see a separate section of the paper devoted to explaining - What do we think the semantics of `x &= y` are, when `x` is volatile? Is it a load-modify-store? Is it an atomic modify-in-place? Is it *allowed* to be an atomic modify-in-place? Is it allowed to use special crazy flag-setting instructions? Basically what are programmers hoping to get when they write that line of code, and, what are they thinking they *mustn't* get? - If the answer to the first question is "We don't know, it's implementation-defined or worse, but as embedded programmers we just need the syntax to keep compiling so that our code doesn't break," then that's an honest answer (I guess) but it needs to be really clearly stated in this separate section. My goal with the separate section would be to try not to devolve the discussion into a flamewar about the (lack of) meaning of `volatile` in general, but to clearly indicate to the reader that you've *thought* about its (lack of) meaning. ---- Oh, and finally, consider the following workaround: *(int*)myvolatilevar &= 255; Compound assignments on non-volatile variables aren't deprecated; so if you really need the compound stuff more than any particular semantics provided by the volatile stuff, could you just add the cast? –Arthur
Received on 2021-02-12 08:46:02