CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Jul 2008
    Posts
    32

    Assigning value to a volatile string

    Hi,

    I've been trying this for awhile and I'm just about to give up and use volatile char* instead. I cannot even get this to work with a simple example. What am I missing?

    Here's the most simple example I can think of that illustrates my problem:

    Code:
    #include <string>
    using namespace std;
    
    volatile string blah;
    
    int main(int argc, char** argv) {
            blah = "";
    }
    Here's the compiler error, compiled with g++:

    Code:
    main.cpp: In function ‘int main(int, char**)’:
    main.cpp:7: error: passing ‘volatile std::string’ as ‘this’ argument of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]’ discards qualifiers
    I can't even make sense of that error. string.assign() gives a similar error.

  2. #2
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Assigning value to a volatile string

    In general, the synthesized assignment operators cannot be used on a volatile object.
    why? because you're saying to the compiler that the object is subject to the changes in value,
    while the assignment operator takes a const parameter.

    I haven't grasped the complete implementation of std::string,
    but in order for the assignment operator to work,
    the const parameter needs to be preceed by the volatile keyword.
    You can find out if this is implemented in std::string or not.

    EDIT:
    May I ask why you're doing this?
    Last edited by potatoCode; January 6th, 2010 at 09:05 PM.

  3. #3
    Join Date
    Jul 2008
    Posts
    32

    Re: Assigning value to a volatile string

    In general, the synthesized assignment operators cannot be used on a volatile object.
    why? because you're saying to the compiler that the object is subject to the changes in value,
    while the assignment operator takes a const parameter.
    Based on what I've read these were my thoughts too. I'm doing this because I have some program where I need to read in a string from cin, or something similar, in one thread, and access it from various other threads. I can seem to get it to compile fine with volatile const char*; I'm just curious as to why I'm having such issues with std::string.

    On a side note, I find "volatile const char*" to seem somewhat contradictory, but it compiles.

  4. #4
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Assigning value to a volatile string

    volatile has nothing to do with synchronized access to variables. Use synchronization primitives of your threading library instead. Like CRITICAL_SECTION's in Windows or pthread_mutex_t's in POSIX.

    gg

  5. #5
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: Assigning value to a volatile string

    Quote Originally Posted by MrMojoRisin View Post
    Based on what I've read these were my thoughts too. I'm doing this because I have some program where I need to read in a string from cin, or something similar, in one thread, and access it from various other threads.
    Good motivation with a poor decision I guess
    I can seem to get it to compile fine with volatile const char*; I'm just curious as to why I'm having such issues with std::string.
    Like I said,
    I highly doubt that the developers of std::string would have used the volatile qualifer
    in the implementation of operator= (or for anyother functions)
    On a side note, I find "volatile const char*" to seem somewhat contradictory, but it compiles.
    You said it.
    There are few things in C++ that doesn't make sense to me.
    volatile is surely one of them.
    Maybe somebody ought to start a whole new thread on this :tongue:

  6. #6
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: Assigning value to a volatile string

    this might be a motivation for the use of volatile and be a proposal for a solution for the OP as well:
    http://www.ddj.com/cpp/184403766
    An implementation of this approach can be found in the loki library.

  7. #7
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Assigning value to a volatile string

    >> this might be a motivation for the use of volatile
    I don't recommend it.

    http://www.codeguru.com/forum/showpo...94&postcount=8

    gg

  8. #8
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: Assigning value to a volatile string

    I agree that volatile has no direct connection to multi-threading. But once you know you have a critical resource, adding volatile to it and using the lockingPtr technique helps to insure that you do not inadvertently access that resource without building a mutex around it. I have used this lockingPtr myself and in comes in handy as a compiler support for accessing critical resources. And it's no compiler extension you rely on, it's the language itself. As with const, the compiler asures you only act on volatile members either in functions declared as volatile or with this mutex thing.

    @Codeplug, do you have any negative experience with this technique?

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Assigning value to a volatile string

    Quote Originally Posted by potatoCode View Post
    There are few things in C++ that doesn't make sense to me. volatile is surely one of them.
    Even though this is 'C' related, it gives an explanation of the uses of volatile.

    http://www.netrino.com/Embedded-Syst...latile-Keyword

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Jul 2008
    Posts
    32

    Re: Assigning value to a volatile string

    I guess I'm confused a bit now as to which strategy to use, as there seem to be a couple opposing views here. Although this is an interesting discussion, maybe I should better describe what I'm specifically trying to do; it's actually a simple concept.

    I have one thread that sits around and waits for some type of keyboard input. This will eventually be in a UI, but for now let's say it's input from the command line. This thread will take the user input and store it in some member variable, say in a std::string.

    Another thread will be doing calculations in the background, and it will also be checking some flag to see if there's new keyboard input. If there is, this thread will read the value of the std::string and do some calculations based on this value. This thread doesn't need to alter the value of the std::string in any way.

    Based on the links provided by Richard.J and Paul_McKenzie it seems as if the volatile keyword is warranted in this situation, as I'm essentially checking a flag, then reading a string. Now, it seems as if the std::string itself doesn't need to be volatile, as the worker thread will only read it after the flag is set. However, wouldn't the flag itself need to be volatile, as described in the above links?

  11. #11
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Assigning value to a volatile string

    >> @Codeplug, do you have any negative experience with this technique?
    Never employed it.
    It's just a shame that so many people "glance" at that article and then think that the volatile keyword provides any kind of meaningful semantics to a variable that's accessed by multiple threads - it doesn't.

    >> Even though this is 'C' related, it gives an explanation of the uses of volatile.
    >> http://www.netrino.com/Embedded-Syst...latile-Keyword
    Unfortunately, the "Multi-threaded applications" section is dead wrong. What's more unfortunate is that this kind of misinformation is all over the net.

    >> I guess I'm confused a bit now as to which strategy to use...
    The overall strategy is this:
    Applications shall ensure that access to any memory location by more than one thread of control (threads or processes) is restricted such that no thread of control can read or modify a memory location while another thread of control may be modifying it. Such access is restricted using functions that synchronize thread execution and also synchronize memory with respect to other threads. ... Applications may allow more than one thread of control to read a memory location simultaneously.
    That's right from the Posix standard. Same goes for Windows compilers.
    http://www.opengroup.org/onlinepubs/...html#tag_04_10

    Use a CRITICAL_SECTION or pthread_mutext_t to synchronize access to your std::string - or any shared variable.

    gg

  12. #12
    Join Date
    Jul 2008
    Posts
    32

    Re: Assigning value to a volatile string

    Thanks for the reply. I understand what you're saying, and I most certainly cannot argue about what's in the C++ standard, but I'm still hung up about this, from Richard.J's link (http://www.ddj.com/cpp/184403766):

    Suppose the compiler figures out that Sleep(1000) is a call into an external library that cannot possibly modify the member variable flag_. Then the compiler concludes that it can cache flag_ in a register and use that register instead of accessing the slower on-board memory. This is an excellent optimization for single-threaded code, but in this case, it harms correctness: after you call Wait for some Gadget object, although another thread calls Wakeup, Wait will loop forever.
    It seems to be saying that the Wait function will not see the change to the flag_ variable because it's cached in a register unknown to the Wait function, hence the use of volatile. Is this actually the case, or is there something missing somewhere?

  13. #13
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Assigning value to a volatile string

    The example code is incorrect because two are more threads can read or modify 'flag_' without using "functions that synchronize thread execution". The rule is still broken even after marking 'flag_' as volatile. As far as Posix is concerned, it's incorrect either way.

    volatile is never needed when using the synchronization primitives provided by your threading library.

    gg

  14. #14
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: Assigning value to a volatile string

    What I wanted to say is this:
    1. multi-threaded access to a shared resource _must_ be protected by a mutex (even if it is only a read, as some-thread else might be writing to it.
    2. the use of the keyword volatile _alone_ does not make anything thread-safe
    3. But the combined use of the keyword volatile and the use of the lockingPtr concept adds a compile-time check for the use of concurrent resources and it's definitely worth having a look at.

    I have read most of the discussions in the thread (and links) that Codeplug referred to this afternoon, but in my opinion, they all concentrate on the question "does the keyword 'volatile' make the access to a variable thread-safe?". NO, it doesn't. Only the combination of 2. and 3. above adds some (compiler) help to the programmer to get it right. There might be hacks to circumvent this, and if compiler optimization matters, it might be counter-productive, but I personally find it useful.

  15. #15
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Assigning value to a volatile string

    It's certainly true that compile-time checks are always a good thing, and the described usage of the volatile keyword is one means of doing that.

    The criticism is that this is the very definition of a hack: You're using a keyword for a purpose completely unrelated to its original intention.

    I'd be in favor of that sort of locking_ptr mechanism if there were a keyword which had absolutely no other purpose devoted to it; but co-opting the volatile keyword for that purpose can be confusing to any developer who hasn't been introduced to the technique, so I'd suggest against it.

    In regards to the OP's needs: I think a std::queue<std::string> with a read/write lock around it (pthread_rwlock) would be ideal. Use the read lock whenever you call top(), and use the write lock whenever you call push() or pop(). If you're only handling the input on a single thread, or it if you want to ensure that each input is only handled by one thread, then a simple mutex might be more appropriate.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured