5

I have a

volatile std::queue<int> requestQueue;

and when I try to call within a function any of its methods (pop, push, empty, front etc), e.g.:

    while (!requestQueue.empty()){
        ...do something
    }

I get the following error.

robot.cpp:43:31: error: passing 'volatile std::queue<int>' as 'this' 
argument of 'bool std::queue<_Tp, _Sequence>::empty() 
const [with _Tp = int, _Sequence = std::deque<int, std::allocator<int> >]'
discards qualifiers [-fpermissive]

I found online that a typecast might be needed, but I am not sure whether this is the case.

Any ideas? Thanks in advance.

Update

1) The program uses such a data structure to store a sequence of requests so that a server can take the requests at its own service rate.

2) volatile is used to support data sharing between functions running on different cores.

3) The documentation of the library I use states the following regarding the use of

  • Use static volatile to declare global variables for sharing between functions running in different cores.
STiGMa
  • 906
  • 3
  • 11
  • 24
  • Why do you use `volatile`? – cpplearner Jul 12 '15 at 11:17
  • It's hard to tell you how to correctly do whatever it is you're trying to do when you don't tell us what it is you're trying to do. The `empty` function has no idea what you're trying to do either, so it's telling you it has no way to do whatever it is you might be trying to do. – David Schwartz Jul 12 '15 at 11:19
  • @cpplearner it's a requirement (*must*) in my application. Basically, it is used to support data sharing between functions running on different cores. – STiGMa Jul 12 '15 at 11:20
  • 1
    @STiGMa That's a common misunderstanding. Since `volatile` is [neither necessary nor sufficient](http://stackoverflow.com/a/2485177/721269) it's basically useless for this purpose. If you want a thread-safe queue, use a `std::mutex` to protect the queue. If it must be waitable, use a condition variable too. I think your real question is, "How do I implement a thread-safe, waitable queue in C++?" – David Schwartz Jul 12 '15 at 11:22
  • @STiGMa Do you have some very unusual compiler or very unusual platform or are you writing kernel code? Otherwise, "*Use static volatile to declare global variables for sharing between functions running in different cores,*" makes no sense because `volatile` (in C/C++) has no defined inter-core semantics. – David Schwartz Jul 12 '15 at 11:51
  • @DavidSchwartz thanks; it makes sense now. I am going through all this information and I will get back if I have any further issues/don't manage to resolve the issue. Mutex might not be applicable because the compiler is limited to C++98, but a solution with semaphores might work too, I guess. – STiGMa Jul 12 '15 at 12:00
  • 1
    @STiGMa If it's C++98, how are you creating threads? Or is the code on one core running in the kernel? Or is this processes sharing memory? (And if this is not threads, how is the queue supposed to work at all?) – David Schwartz Jul 12 '15 at 12:02

2 Answers2

8

You're expecting volatile to work impossible magic. It is simply the case that std::queue is not a thread-safe queue, nor is it a waitable queue. You can make a thread-safe, waitable queue if you want, but just attaching volatile to std::queue won't magically conjure the code necessary to do that out of nowhere.

This is a common misunderstanding about what volatile does. It some cases, on some platforms, it happens to do what you happen to need to make some things work between cores. But that's always by a combination of accident and luck. It's almost never the right way to synchronize across cores in C or C++.

I suspect that your real question is, "How do I make a thread-safe, waitable queue in C++?" And the answer is to use a std::mutex to make it thread-safe, and a std::condition_variable to make it waitable. These things are not simple to use, and some expertise is needed, so you may prefer to find a suitable queue that is already written.

If your code isn't C++11, then we'll need to know how you're creating threads to know how you should be synchronizing them. Windows threads has ways, POSIX threads has ways. If this isn't threads (maybe it's processes sharing memory or something like that) then std::queue is not even remotely close to what you need -- it can't possibly work because std::queue uses pointers internally, and those won't work across processes.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
5

The queue member functions are not volatile-qualified, so you cannot use them on volatile queue instances. Basically, if you must have something volatile, then this is not the data structure you are looking for.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Didn't know that; Thanks. I *must* use volatile. The aim, basically, is to store a sequence of requests so that a server can take the requests at its own service rate. Do you know any data structure that fits this? – STiGMa Jul 12 '15 at 11:18
  • @STiGMa Since nobody has any idea what `volatile` does here, how can it be the case that you must use it? You must do something that has no defined effect?! Are you looking for a thread-safe queue? – David Schwartz Jul 12 '15 at 11:20
  • 1
    Don't you se the standard library then. It's not suitable for that purpose. You can write your own data structure. Something tells me, though, that you might be misunderstanding the purpose of `volatile` and there might be an entirely different, elegant solution. – Kerrek SB Jul 12 '15 at 11:21
  • Just wrote a 3 bullets update about the purpose/requirement of using volatile. – STiGMa Jul 12 '15 at 11:27
  • 2
    @STiGMa: I'm not privy to (nor interested in) the details, but a cursory glance at those bullets leads me to believe that You're Doing Everything Wrong. Volatile is for accessing floppy disk controllers, not for multithreading. (I could be completely wrong, in which case please do ignore me,) – Kerrek SB Jul 12 '15 at 11:36
  • @KerrekSB You are right. See [this article](https://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming) that explains what `volatile` is for in C/C++. (It's different in, for example, Java.) – David Schwartz Jul 12 '15 at 11:53