1

I have a class that has declared a static volatile QHash

class Sample
{
    volatile static QHash <string, int> myDict;
}

And I am using a class to override the run() method of QThread

class MyThread : public QThread
{
public:
    void run()
    {
        string s = "hello";
        if(Sample::myDict.contains(s)){std::cout << "i contain "<< s;}
    }
}

But doing this gives me a compilation error :

passing 'volatile QHash<std::string, int>' as 'this' argument of 'bool QHash<Key, T>::contains(const Key&) const [with Key = std::string; T = int]' discards qualifiers [-fpermissive]

So I checked on stack overflow. It seems that passing volatile variables to functions makes the compiler give a warning because compiler can do thread unsafe optimizations w.r.t that variable. But in my case, the compiler is giving an error instead of a warning. Also, here the volatile QHash seems to be an implicit argument to the function "QHash::contains". Any help?

ishan3243
  • 1,870
  • 4
  • 30
  • 49
  • 2
    Indeed, you can't call a non-volatile function of a volatile object, just as you can't call a non-const function of a const object. Why is it volatile in the first place? I can't think of any good reason for that. – Mike Seymour Jul 08 '14 at 07:50
  • That method isn't [volatile-correct](http://stackoverflow.com/questions/5106196/c-what-does-volatile-represent-when-applied-to-a-method) (analogous to const-correctness and const member functions). – Cornstalks Jul 08 '14 at 07:50
  • @MikeSeymour isn't it supposed to be volatile if its being accessed by multiple threads? – ishan3243 Jul 08 '14 at 07:51
  • 3
    Also, you probably shouldn't be using `volatile`, and instead should be using proper mutex locks or atomic wrappers. `volatile` has nothing to do with threads. – Cornstalks Jul 08 '14 at 07:51
  • 4
    @ishan3243: No, `volatile` has nothing to do with threads. You'll need a mutex or similar to guard access to it. (`std::mutex` from the C++11 standard library, or `QMutex` from Qt, would be suitable.) – Mike Seymour Jul 08 '14 at 07:51
  • @MikeSeymour but what about this? http://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/ Check point 2). It tells about multithreading – ishan3243 Jul 08 '14 at 07:54
  • 8
    @ishan3243: That's just plain wrong. `volatile` doesn't give the atomic access needed to safely modify data that's accessed by other threads. It might appear to work by accident for primitive types on most common platforms, if the underlying hardware operations happen to be atomic - but not for complex types like `QHash`. – Mike Seymour Jul 08 '14 at 08:00
  • volatile today is keyword for parameters that can be changed out of thread (to say compiler to not optimize it), it gives no atomic access, language has it not for threads manipulation, but for reading info from ports and etc. – Arkady Jul 08 '14 at 08:00
  • @ishan3243: The article ["Do not use volatile as a synchronization primitive"](https://www.securecoding.cert.org/confluence/display/cplusplus/CON01-CPP.+Do+not+use+volatile+as+a+synchronization+primitive) linked at the bottom of that article seems rather more accurate (although I haven't read it in detail). See also http://www.drdobbs.com/parallel/volatile-vs-volatile/212701484. – Mike Seymour Jul 08 '14 at 08:05
  • @MikeSeymour, as I remember, it was possible to use 1 bytes volatile types (such as unsigned char) as flag for multithreading messaging, because one byte can't be partially read or written. – Arkady Jul 08 '14 at 08:10
  • 2
    @Arkady: On some platforms, yes. But there's no portable guarantee; for example, on a multi-core platform, changes made on one core might not propagate to others without the correct synchronisation primitives. C++11 gives atomic types, which do give the necessary guarantee for primitive types. (But we're getting off-topic here; the question is about a complex user-defined type, which needs synchronisation with a mutex or similar). – Mike Seymour Jul 08 '14 at 08:14

0 Answers0