Re: volatile Keyword Question

Discussion in 'C Programming' started by Eric Sosman, Nov 30, 2008.

  1. Eric Sosman

    Eric Sosman Guest

    Jujitsu Lizard wrote:
    > Hi,
    >
    > In embedded work I'm doing, some of the interrupt hardware requires that
    > you read it before you write it to clear the interrupt.
    >
    > So, the code I use might look something like this:
    >
    > volatile unsigned char control_reg; //Placed at a specific memory
    > location by other mechanisms.
    >
    > void interrupt_service_routine(void)
    > {
    > if (control_reg)
    > ; //Note the semicolon--empty statement. This statement is just
    > intended to
    > //force a discarded read.
    >
    > control_reg = 0x00;
    > }
    >
    > There was a thread on comp.arch.embedded where it was suggested that the
    > compiler has no obligation to read control_reg before writing it because
    > the result is not actually used.
    >
    > Is this true? I thought the compiler was required to read the volatile
    > because it was volatile?
    >
    > The construct above has always worked for me.
    >
    > Am I doing the wrong thing?


    You're fine[*]. Reading from or writing to a `volatile'
    variable is a side-effect, and the compiler is not allowed to
    discard side-effects. In

    if (printf("Hello, world!\n"))
    ;

    the compiler is not allowed to omit the printf() call, even
    though its result is just as unused as your read of `control_reg'.

    [*] Almost. The compiler must generate code that performs
    the accesses you call for, but the nature of those accesses is
    implementation-defined. You can't be sure that `control_reg'
    will be read with a "load byte" or cleared with a "store byte"
    if other instruction sequences are available. If the register
    is sensitive to one type of instruction but reacts improperly
    to others, you'll need to check the compiler's documentation to
    make sure it will generate what you need.

    --
    Eric Sosman
    lid
    Eric Sosman, Nov 30, 2008
    #1
    1. Advertising

  2. Eric Sosman

    Thad Smith Guest

    Jujitsu Lizard wrote:

    > I've noticed that if I use:
    >
    > if (control_reg) ;
    >
    > or
    >
    > control_reg;
    >
    > the compiler will use a "TST _control_reg" instruction which is fine
    > because it generates a read cycle.
    >
    > On the other hand, if I say:
    >
    > i = control_reg;
    >
    > naturally TST won't do the trick as it doesn't move the data anywhere
    > usable.


    No, but the compiler should use another instruction, such as LOAD or MOV
    to access control_register, still generating the needed read cycle for
    your purpose.

    --
    Thad
    Thad Smith, Dec 1, 2008
    #2
    1. Advertising

  3. Eric Sosman

    Thad Smith Guest

    Jujitsu Lizard wrote:
    >


    Addendum: I put a little bit of test code through my favorite
    > microcontroller compiler. I pasted it in below.
    >
    > tf9() is interesting. It is interesting that the compiler rules allow
    > the write to the non-volatile variable to be combined and delayed.

    ....
    unsigned char c_nv;
    > volatile unsigned char c_v;
    > unsigned char temp;
    >
    > void tf1(void)
    > {
    > temp = c_nv;
    > }

    ....
    > void tf9(void)
    > {
    > c_nv = 32;
    > c_v = 29;
    > c_nv = 43;
    > }

    ....

    > 67 ; 47 void tf9(void)
    > 67 ; 48 {
    > 68 0029 _tf9:
    > 70 ; 49 c_nv = 32;
    > 71 ; 50 c_v = 29;
    > 72 0029 a61d lda #29
    > 73 002b c70001 sta _c_v
    > 74 ; 51 c_nv = 43;
    > 75 002e a62b lda #43
    > 76 0030 c70002 sta _c_nv
    > 77 ; 52 }
    > 78 0033 81 rts


    It appears to me me that the superfluous assignment of 32 has been
    removed. Otherwise execution is in order, nothing combined, nothing
    delayed. If the compiler cannot prove that c_nv isn't used after the
    call to tf9, it must store the final value from executing the function.

    Your compiler appears, in your tests, to conform to restrictions on
    volatile while eliminating unused references.

    --
    Thad
    Thad Smith, Dec 1, 2008
    #3
  4. Eric Sosman

    George Guest

    On Sun, 30 Nov 2008 20:39:27 -0500, Jujitsu Lizard wrote:


    > I agree that the compiler is legal.


    What compiler are you using?

    --
    George

    On September 11 2001, America felt its vulnerability even to threats that
    gather on the other side of the Earth. We resolved then, and we are
    resolved today, to confront every threat from any source that could bring
    sudden terror and suffering to America.
    George W. Bush

    Picture of the Day http://apod.nasa.gov/apod/
    George, Dec 1, 2008
    #4
  5. Eric Sosman

    George Guest

    On Mon, 1 Dec 2008 18:03:51 -0500, Jujitsu Lizard wrote:

    > "George" <> wrote in message
    > news:zn75zoe9pkt7$.l76cwo251uh0$...
    >> On Sun, 30 Nov 2008 20:39:27 -0500, Jujitsu Lizard wrote:
    >>
    >>
    >>> I agree that the compiler is legal.

    >>
    >> What compiler are you using?

    >
    > I decline to say.
    >
    > Why do you want to know?
    >
    > The Lizard


    I didn't mean to get personal. I was hoping to get the same assurance that
    my compiler conforms for the tool that I've chosen for my own project,
    which is winavr.

    Maybe we could address this back in comp.arch.embedded?
    --
    George

    The United States and our allies are determined: we refuse to live in the
    shadow of this ultimate danger.
    George W. Bush

    Picture of the Day http://apod.nasa.gov/apod/
    George, Dec 2, 2008
    #5
  6. Eric Sosman

    Richard Bos Guest

    Eric Sosman <> wrote:

    > Jujitsu Lizard wrote:
    > > Is this true? I thought the compiler was required to read the volatile
    > > because it was volatile?


    > You're fine[*]. Reading from or writing to a `volatile'
    > variable is a side-effect,


    Wrong in theory, correct in practise. _Accessing_ a volatile object is a
    side-effect, but "What constitutes an access that has volatile-qualified
    type is implementation-defined", sayeth the Standard. Luckily, AFAIAA
    every single C implementation out there does count reading and writing
    as "accesses", but strictly speaking they don't have to. You'd have to
    be pretty much out to pester your customers not to do so, as an
    implementation writer, though, so expect this to work everywhere except
    on later model Deathstations.

    Richard
    Richard Bos, Dec 2, 2008
    #6
  7. Eric Sosman

    Tim Rentsch Guest

    (Richard Bos) writes:

    > Eric Sosman <> wrote:
    >
    > > Jujitsu Lizard wrote:
    > > > Is this true? I thought the compiler was required to read the volatile
    > > > because it was volatile?

    >
    > > You're fine[*]. Reading from or writing to a `volatile'
    > > variable is a side-effect,

    >
    > Wrong in theory, correct in practise. _Accessing_ a volatile object is a
    > side-effect, but "What constitutes an access that has volatile-qualified
    > type is implementation-defined", sayeth the Standard. Luckily, AFAIAA
    > every single C implementation out there does count reading and writing
    > as "accesses", but strictly speaking they don't have to. You'd have to
    > be pretty much out to pester your customers not to do so, as an
    > implementation writer, though, so expect this to work everywhere except
    > on later model Deathstations.


    This interpretation is a misreading. The term "access" is defined, in
    3.1 --

    <<execution-time action>> to read or modify the value of an object

    What 6.7.3 p 6 means with the "What constitues an access ..." sentence
    is that (a) what else /besides/ reading a variable's value or assigning
    a new value into it constitutes an access, (b) for getting a stored
    value or storing a new value, which other memory locations may be
    accessed, because other memory locations other than the object being
    referenced directly may be accessed by necessity of the implementation.

    But getting a variable's value, or assigning a new value to it,
    is always an access of that variable's object.
    Tim Rentsch, Dec 3, 2008
    #7
  8. Eric Sosman

    Guest

    Tim Rentsch <> wrote:
    >
    > What 6.7.3 p 6 means with the "What constitues an access ..." sentence
    > is that (a) what else /besides/ reading a variable's value or assigning
    > a new value into it constitutes an access, (b) for getting a stored
    > value or storing a new value, which other memory locations may be
    > accessed, because other memory locations other than the object being
    > referenced directly may be accessed by necessity of the implementation.
    >
    > But getting a variable's value, or assigning a new value to it,
    > is always an access of that variable's object.


    No, 6.7.3p6 was intended to be a gaping loophole. In particular, an
    implementation that has no desire to support any kind of concurrency is
    free to completely ignore volatile.
    --
    Larry Jones

    OK, there IS a middle ground, but it's for sissy weasels. -- Calvin
    , Dec 3, 2008
    #8
  9. Eric Sosman

    George Guest

    On Wed, 03 Dec 2008 01:46:02 +0000, Richard Heathfield wrote:

    > Jujitsu Lizard said:
    >
    >> "George" <> wrote in message
    >> news:zn75zoe9pkt7$.l76cwo251uh0$...
    >>> On Sun, 30 Nov 2008 20:39:27 -0500, Jujitsu Lizard wrote:
    >>>
    >>>
    >>>> I agree that the compiler is legal.
    >>>
    >>> What compiler are you using?

    >>
    >> I decline to say.
    >>
    >> Why do you want to know?

    >
    > Presumably just curiosity, and obviously you have no obligation to sate it.
    > If the compiler were relevant to your question, you wouldn't be asking it
    > here!


    Given that implementations do what the standard "should," a headcount of
    what they do--and what mine will do--is apropos.

    In a very real sense, I don't care what The Lizard makes for personal
    decisions, except that his experience seems relevant to my lack thereof, as
    it concerns C and volatile.

    I hope to pursue this line withhim in comp.arch.embedded.
    --
    George

    We cannot let terrorists hold this nation hostile or hold our allies
    hostile.
    George W. Bush

    Picture of the Day http://apod.nasa.gov/apod/
    George, Dec 5, 2008
    #9
  10. Eric Sosman

    Tim Rentsch Guest

    writes:

    > Tim Rentsch <> wrote:
    > >
    > > What 6.7.3 p 6 means with the "What constitues an access ..." sentence
    > > is that (a) what else /besides/ reading a variable's value or assigning
    > > a new value into it constitutes an access, (b) for getting a stored
    > > value or storing a new value, which other memory locations may be
    > > accessed, because other memory locations other than the object being
    > > referenced directly may be accessed by necessity of the implementation.
    > >
    > > But getting a variable's value, or assigning a new value to it,
    > > is always an access of that variable's object.

    >
    > No, 6.7.3p6 was intended to be a gaping loophole. In particular, an
    > implementation that has no desire to support any kind of concurrency is
    > free to completely ignore volatile.


    Beyond the single posting quoted above, I've found no confirming
    evidence that supports the stated assertion; in fact, rather the
    opposite. For starters, it's contradicted by the plain text of the
    Standard. 6.7.3p6 (the very same paragraph) says:

    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. [...]

    Expressions that don't reference volatile variables may be optimized
    under the "as if" rule, but those with volatile variables may not.
    Notice that this applies to the entire containing expression, not just
    those parts that reference volatile variables. Ignoring volatile
    qualifiers would violate this requirement.

    Besides 6.7.3p6, the Standard contains statements touching on the
    semantics of volatile in 5.1.2.3p2,3,5; 5.1.2.3p8,9 (Examples);
    6.7.3p5; and footnotes 6.2.4p2(26), 6.7.3p3(114), and 6.7.3p6(116).
    None of these statements give any indication of the "gaping loophole"
    suggested above, and again more to the contrary -- for example, this
    footnote [6.7.3p6(116)]:

    A volatile declaration may be used to describe an object corresponding
    to a memory-mapped input/output port or an object accessed by an
    asynchronously interrupting function. Actions on objects so declared
    shall not be ``optimized out'' by an implementation or reordered
    except as permitted by the rules for evaluating expressions.

    This footnote is referenced in the same paragraph as the "What constitutes
    an access ..." statement about volatile variables; if there really were
    a "gaping loophole" intention this footnote would have been a natural
    place to express it. Yet there is no such expression.

    Another place we might look is defect reports. The word volatile appears
    in DRs 8, 17, 40, 67, 106, 113, 123, 124, 149, 152, 272, and 301. Most
    of these don't have anything to do with the semantics of volatile; really
    only DR 8, which asks about volatile being required for automatic variables
    in the same function as a setjmp. Again no indication of any loophole.

    Since the suggestion was made as to the committee's intent, it's
    reasonable to look in the Rationale document (latest version is at
    http://www.open-std.org/jtc1/sc22/wg14/www/docs/C99RationaleV5.10.pdf).
    It contains these paragraphs pertaining to volatile:

    Page 75 [defining the volatile qualifier]

    volatile

    No cacheing through this lvalue: each operation in the abstract
    semantics must be performed (that is, no cacheing assumptions may be
    made, since the location is not guaranteed to contain any previous
    value). In the absence of this qualifier, the contents of the
    designated location may be assumed to be unchanged except for possible
    aliasing.

    Page 76

    A static volatile object is an appropriate model for a memory-mapped
    I/O register. Implementors of C translators should take into account
    relevant hardware details on the target systems when implementing
    accesses to volatile objects. For instance, the hardware logic 20 of
    a system may require that a two-byte memory-mapped register not be
    accessed with byte operations; and a compiler for such a system would
    have to assure that no such instructions were generated, even if the
    source code only accesses one byte of the register. Whether
    read-modify-write instructions can be used on such device registers
    must also be considered. Whatever decisions are adopted on such
    issues must be documented, as volatile access is implementation-defined.
    A volatile object is also an appropriate model for a variable shared
    among multiple processes.

    The second paragraph is interesting because it mentions explicitly the
    implementation-defined aspect. Note however it doesn't say anything
    about optimizing away accesses to volatile variables; rather it
    states a need to document how volatile accesses will be carried out.
    This interpretation fits with the plain text of the Standard,

    What constitutes an access to an object that has
    volatile-qualified type is implementation-defined.

    to mean "what actions /make up/ an access" to a volatile object is
    what is implementation defined. But still no indication that whatever
    actions make up a volatile access might not take place at run time.

    Until someone can point out some statement, even a non-normative one,
    that appears anywhere in any official ISO document and even hints at
    some sort of loophole along the lines of what was suggested above, it
    seems better to follow an interpretation more consistent with what the
    documents actually say. I think I'm as willing as the next person to
    grant some latitude as to how ideas are expressed in the technical
    prose of the ISO C documents, but there needs to be at least some hint
    of expression before a proposed viewpoint can be seriously considered.
    Here I have found none.
    Tim Rentsch, Dec 19, 2008
    #10
  11. Eric Sosman

    Tim Rentsch Guest

    writes:

    > Tim Rentsch <> wrote:
    > >
    > > writes:
    > > >
    > > > No, 6.7.3p6 was intended to be a gaping loophole. In particular, an
    > > > implementation that has no desire to support any kind of concurrency is
    > > > free to completely ignore volatile.

    > >
    > > Beyond the single posting quoted above, I've found no confirming
    > > evidence that supports the stated assertion;

    >
    > I was there for the committee discussions. Furthermore, one of the
    > major objections to Clive Feather's formal model for sequence points was
    > that it somewhat more fully defined volatile accesses and a number of
    > committee members were adamantly opposed to doing that.


    I understand that it's your opinion of what happened. My point is
    that until there is some sort of supporting statement somewhere in
    some official ISO document I don't see any reason for anyone to take
    it as a statement of what the Standard actually expresses. If a C1X
    draft appeared with even a footnote along these lines, I'd be more
    than happy to take the footnote as gospel. Absent such any official
    confirmation, however, I think the standard should be judged based on
    whatever text the official documents actually contain. If no official
    text can be pointed to that supports the expressed opinion, it seems
    wrong to give it any official weight.
    Tim Rentsch, Dec 23, 2008
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Harald Kirsch

    Is volatile keyword necessary?

    Harald Kirsch, Mar 4, 2004, in forum: Java
    Replies:
    2
    Views:
    343
    Chris Uppal
    Mar 4, 2004
  2. ben
    Replies:
    5
    Views:
    583
    Ulrich Eckhardt
    Jan 11, 2005
  3. Ben Bacarisse

    Re: volatile Keyword Question

    Ben Bacarisse, Nov 30, 2008, in forum: C Programming
    Replies:
    28
    Views:
    780
    Tim Rentsch
    Dec 19, 2008
  4. Borked Pseudo Mailed

    volatile Keyword Question

    Borked Pseudo Mailed, Dec 1, 2008, in forum: C Programming
    Replies:
    0
    Views:
    258
    Borked Pseudo Mailed
    Dec 1, 2008
  5. Nomen Nescio

    volatile Keyword Question

    Nomen Nescio, Dec 3, 2008, in forum: C Programming
    Replies:
    0
    Views:
    266
    Nomen Nescio
    Dec 3, 2008
Loading...

Share This Page