views:

159

answers:

2

I have a class A that I overload its operator=. However it is required that I need to do something like this:

volatile A x;
A y;
x = y;

which raised an error while compiling

error: no operator "=" matches these operands
       operand types are: volatile A = A

If I removed volatile, it's compilable. Is there anyway to have this compiled without removing the "volatile" (and still keep the behavior of volatile) ?


Basically this is a cuda program in which 'x' is a shared memory ( all threads can access and modify its value ). I want it to be "volatile" in order to avoid the compiler optimization and re-use the value instead of accessing the memory address.

More on the problem: at the beginning A is just a primitive type e.g integer, volatile worked as expected and doesn't cause any problem, now I want it to be a custom class ( integer 128-bit for example ). I'm not sure why C++ complain in this case but not with primitive data type.

Thanks in advance.

+5  A: 

Assuming the volatile qualification is necessary, you'll have to add a volatile assignment operator to A (A& A::operator=(const A&) volatile).

const_cast<A&>(x) = y will make it compile, but will technically cause undefined behaviour, and will certainly remove the guarantees that volatile gives.

Mike Seymour
Thanks ! It is compiled. but too bad :(, it gives me the same behavior of no-volatile
iKid
@iKid: what behaviour were you expecting from `volatile`?
Mike Seymour
@Mike: I added explanation to my question
iKid
+3  A: 

volatile isn't a lot of use in C++ threading (see Dave Butenhof's explanation at http://www.lambdacs.com/cpt/FAQ.html#Q56). It's not sufficient to ensure your program flushes the data written out of core-local cache to a point where other programs can see the updates in shared memory, and given almost everyone's multi-core these days, that's a serious problem. I suggest you use proper threading synchronisation methods, such as boost's if your portability needs match it, or perhaps POSIX mutexes and condition variables, failing that more architecture dependent techniques like memory barriers or atomic operations that implicitly sync memory between cores.

I'm sure you want it to be fast, but fast and unstable isn't generally as useful as slow and reliable, especially if you ship a product that's only unstable on your customer's hardware.

Tony
Especially considering that `pthread_mutex`es can be incredibly lightweight
doron
Because everybody runs on POSIX, amirite?
DeadMG
@DeadMG: no, which is why we have portable wrappers like Boost.Thread, and the C++0x thread support library.
Mike Seymour
Exactly. Recommending POSIX directly is just not the right thing to do compared to boost::thread.
DeadMG
Thanks, feeling like C++ was poorly designed in this case
iKid
"volatile isn't a lot of use in C++." This is as much nonsense as saying "const isn't a lot of use in C++." The problem with `volatile` isn't `volatile` but the programmers who think `volatile` is some magical thread synchronization primitive that's broken. It's not.
John Dibling
@DeadMG/Mike: fair call - answer updated. @John: check out the link I inserted - it's not required for inter-thread synchronisation and may harm performance. May still be useful for async signal handling or low-level device control etc., but that's irrelevant to the question... have updated my wording in the answer to reflect that.
Tony
thanks guys, the most frustrated thing here is that it does work in case of primitive data type but in object class. If there is no way to re-use the old one (which I want to keep the speedy) I have to code a very similar method just for the sake of "non-volatile" adaptiveness.
iKid
@iKid: don't let yourself think primitive types "work". Simply being able to compile is no guarantee of reliable results on a multi-CPU/core computer. Even if your testing on such a machine looks fine, it can still break when your program is unlucky enough to be preempted and put onto another CPU... most likely when the host's heavily loaded. You simply must use proper synchronisation mechanisms if you want a reliable program... that's what they're designed for. If you really measure performance with a mutex and it's a problem, you might try an atomic operation.
Tony