Thread: Guaranteed read from volatile variable

  1. #1
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229

    Guaranteed read from volatile variable

    If I have something like
    Code:
    volatile int *ptr = 0xsomeaddress;
    ...
    Would
    Code:
    *ptr;
    guarantee a read on someaddress?

    I saw something like this in an embedded application, and was wondering if this actually works.

    (someaddress is a hardware register, on which a read operation has side effects)

    Thanks!

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Yes. (If you've got the optimizer set to "kill", I suppose it might get blasted, but it really shouldn't.)

  3. #3
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Here are some short but informative reads on the subject: How to Use Volatile Keyword and Volatile Myths
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  4. #4
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    I have always understood volatile as meaning the variable can be changed outside of program flow (the links suggest that also).

    In that case, the optimizer could argue that it can omit the read because the program doesn't care what value it has? since the result of the read is not assigned to anything, or used to make any decision.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Somewhere, the standard says something like "the purpose of evaluating statements is for side effects to occur", so that's not really a reason to not evaluate.

    (EDIT: Of course, I can't speak for your optimizer. But if it will optimize what you have away, it will optimize just about anything else away too.)
    Last edited by tabstop; 08-14-2011 at 10:35 PM.

  6. #6
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Quote Originally Posted by cyberfish View Post
    In that case, the optimizer could argue that it can omit the read because the program doesn't care what value it has? since the result of the read is not assigned to anything, or used to make any decision.
    Yes, I do believe that per the standard 5.1.2.3 when it says :"An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object)." that means if the compiler doesn't see the code get used at all it would still be optimized out regardless of whether or not it was volatile.

    The way I have seen around this is to use the preprocessor directive:
    Code:
    #pragma optimize("", off)
    //code here
    #pragma optimize("", on)
    EDIT: I wasn't suggesting you didn't know about volatile. Just giving you some things I have read in the past.
    Last edited by AndrewHunter; 08-14-2011 at 10:43 PM.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The definition of volatile is that needed side effects are produced.

    (EDIT: I think that should say "that needed side effects are always produced" by a volatile variable. The actual language says that accessing a volatile variable is an observable (like input and output), so can't be elided.)
    Last edited by tabstop; 08-14-2011 at 10:50 PM.

  8. #8
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    Somewhere, the standard says something like "the purpose of evaluating statements is for side effects to occur", so that's not really a reason to not evaluate.

    (EDIT: Of course, I can't speak for your optimizer. But if it will optimize what you have away, it will optimize just about anything else away too.)
    Thanks I didn't know that!

    I am using GCC (cross-compiling for ARM), so I'm guessing that's more or less sane.

    (including any caused by calling a function or accessing a volatile object)
    I think that means the compiler needs to be able to prove that accessing the volatile object has no side effect. For example
    Code:
    volatile int x;
    The compiler knows that reading x has no side effect, because it allocated memory for that variable.

    I don't think it can make that assumption if it's a pointer to some random address it doesn't know.

  9. #9
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    I see, I am still learning how to interpret this darn standard.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by cyberfish View Post
    If I have something like
    Code:
    volatile int *ptr = 0xsomeaddress;
    ...
    Would[code]
    *ptr;
    [/code
    guarantee a read on someaddress?
    That should guarantee that reads ot write to ptr are not simply done in a register for example. I.e
    Code:
    ptr = &foo;
    ptr = &bar;
    but I don't know what guarantees if any, apply to using *ptr

    Normally your volatile variable would not be a pointer.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    I was under the impression that "volatile int *ptr" is a pointer to a volatile int, whereas "int * volatile ptr" is a volatile pointer to an int.

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by cyberfish View Post
    I have always understood volatile as meaning the variable can be changed outside of program flow (the links suggest that also).

    In that case, the optimizer could argue that it can omit the read because the program doesn't care what value it has? since the result of the read is not assigned to anything, or used to make any decision.
    Quite the opposite, actually. The volatile keyword tells the compiler that the variable may change as a result of something invisible to the compiler, and that the compiler needs to care about the changes that occur. If code has multiple reads, and the compiler can see nothing that changes the value, then "volatile" tells the compiler it cannot omit reads.

    To answer the original question though, volatile (like const) is always an attribute of the thing immediately to its left in an expression, unless it is on the left, in which case it refers to the right.

    So
    Code:
    volatile int *ptr = 0xsomeaddress;
    guarantees that *ptr (if it is accessed) will always dereference 0xsomeaddress. It is equivalent to
    Code:
    int volatile *ptr = 0xsomeaddress;
    If you care about ptr itself being changed by something invisible to the compiler, then you need to do
    Code:
    volatile int * volatile ptr = 0xsomeaddress;
    (noting that the first usage of volatile can be either before or after the int keyword).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    To answer the original question though, volatile (like const) is always an attribute of the thing immediately to its left in an expression, unless it is on the left, in which case it refers to the right.
    I don't think that was the original question . I understand the left/right syntax.

    Quite the opposite, actually. The volatile keyword tells the compiler that the variable may change as a result of something invisible to the compiler, and that the compiler needs to care about the changes that occur. If code has multiple reads, and the compiler can see nothing that changes the value, then "volatile" tells the compiler it cannot omit reads.
    The thing is, in this case, the code doesn't actually care what that value is. The variable can change all it wants, and the compiler doesn't really care. By your definition, the read can be omitted (in the compiler's point of view, the code will still work correctly no matter how the variable changes).

  14. #14
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    A similar question would be, do writes to volatile variables have to happen?

    If they don't, using them to share variables in multithreading would be very bad...

  15. #15
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The point is that the compiler is generally not allowed to eliminate accesses (read or writes) of a variable. It cannot exclude the possibility that accessing has some effect not visible to it. The clauses in the standard relate to something in the implementation (for example, a linker) that has visibility of a complete program, and can determine that a variable declared as volatile is never accessed.

    While it is true that an optimiser can determine that the value read from a volatile variable is never used (within the function that accessed the value), it is practically a pretty aggressive optimiser that will remove the read. Why? Because a fair few programmers have used the trick you asked about, and screamed rather loudly about "over-aggressive optimisers".

    Generally writes to volatile variables have to happen. Very few compiler vendors would be brave enough to eliminate them.

    However, if a variable is to be accessed by multiple threads, declaring it volatile is neither necessary nor sufficient to ensure reads/writes work correctly. Declaring a variable as volatile certainly does not stop a thread that is reading or writing a volatile variable from being preempted part way through the operation. (Basic operations, such as reading or writing an int or pointer are not guaranteed to be atomic).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Guaranteed Padding?
    By golfinguy4 in forum C++ Programming
    Replies: 5
    Last Post: 01-03-2011, 03:59 PM
  2. Guaranteed weight loss
    By Glirk Dient in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 05-12-2004, 06:11 AM
  3. Replies: 5
    Last Post: 04-16-2004, 01:29 AM