15

I want to assign an object to volatile object in the same type, but failed to do so with compiler error. How to change the program to make it? Besides to make it to work, why i can't do it directly?

I used Visual Studio 2010 as compiler here.

class A
{
public:
};

int _tmain()
{
    A a;
    volatile A va;
    va = a;        // compiler error:C2678 here
    return 0;
}
Thomson
  • 20,586
  • 28
  • 90
  • 134
  • 2
    `const` and `volatile` are two faces of the same coin; they're so related that the Standard often refers to them as `cv-qualifiers`. Have a look at this : http://stackoverflow.com/questions/4479597/does-making-a-struct-volatile-make-all-its-members-volatile/4479652 – Nawaz Jan 10 '11 at 06:48

2 Answers2

22

You need to define an assignment operator function for A with the volatile qualifier.

class A
{
    public:

    volatile A& operator = (const A& a) volatile
    {
      // assignment implementation
    }
};

If you don't define an assignment operator for a class, C++ will create a default assignment operator of A& operator = (const A&);. But it won't create a default assignment operator with the volatile qualifier, so you need to explicitly define it.

Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • 1
    Thanks. I think the return type should be `volatile A&` – Thomson Jan 10 '11 at 06:46
  • 2
    How do you cleanly solve this problem if you don't control the `struct` type because it comes from a platform header file? – Kaz Sep 22 '15 at 20:31
  • Please write cv qualifiers in the correct place, AFTER the type name. Despite the syntax, its the reference which is cv-qualified: `A volatile&` not the base type. – Yttrill Nov 15 '18 at 14:25
  • 1
    That's not true. `A volatile&` and `volatile A&` mean exactly the same, and both apply `volatile` for the reference. A difference would be between `volatile A*` and `A* volatile`, although you can't use the latter with a reference type. – Ethouris Jan 09 '19 at 10:56
0

I have encounted the same question. For example:

struct A { int i; }
volatile A a;
A b;
a = b;   // C2678 here.

I found this method to resolve it:

const_cast<A &>(a) = b;
  • 2
    You can't cast away the volatile, your code has undefined behavior. – James Johnston Jun 26 '14 at 20:26
  • @JamesJohnston Do you have a cleaner solution for cases when you don't control the struct definition? (Like when it comes from a system API header?) I have gone with this solution. I don't believe the behavior is undefined because this is not the `const` qualifier. Assignment to an object is allowed whether or not it is `volatile`, and `volatile` isn't a special kind of access; the qualifier just affects optimization (whether two or more accesses are merged into one). That doesn't matter in my particular situation; it cannot possibly be a problem. – Kaz Sep 22 '15 at 20:30
  • Sorry but I think you are wrong and the behavior IS undefined. See http://stackoverflow.com/a/7368038/562766 -- from C11: "An attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type (6.7.3)" --- in the example above, volatile is casted away from "a", which was originally defined with volatile, and then it is assigned. The correctness of your code is now at the mercy of the optimizer. – James Johnston Sep 22 '15 at 20:48
  • 1
    @JamesJohnston do you have a suggestion for the problem brought up by Kaz, namely needing to perform an assignment where you don't have control over the class definition? – iheanyi Oct 08 '19 at 18:48