C++ Logo

sg14

Advanced search

Re: [SG14] Challenging the deprecation of volatile compound statements

From: connor horman <chorman64_at_[hidden]>
Date: Fri, 12 Feb 2021 10:29:28 -0500
If I may add my $.02, I would like to add my experience in targetting
(albeit not completely) the 65816 processor, and in particular, the Super
Nintendo Entertainment System. In my case (since I provide symbols to users
(and those users are primarily myself), rather than macros) refactoring to
a = a_at_v would not be an issue, though it is a bit unwieldy over a@=v (not
so much to cause anything more than minor annoyance).

On Fri, Feb 12, 2021 at 09:46 Arthur O'Dwyer via SG14 <sg14_at_[hidden]>
wrote:

> 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.)
>
> ---
>
> > 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.
>
I would argue that, as the standard is written, both would be equally
susceptible to bugs caused by accessing things which are also modified in
ISRs (My solution was to save the value of the hardware registers and a
number of MMIO registers into a special region of memory as part of the
prelude of interrupt handlers). To me, it seems easier to allow x &= y to
be in-place, for implementations where this matters, than x = x & y;,
which, as written, seems like it would always have to imply a separate read
and write to x.

>
> ----
>
> > 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
> _______________________________________________
> SG14 mailing list
> SG14_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>

Received on 2021-02-12 09:29:42