volatile struct = struct not possible, why?

十年热恋 提交于 2019-12-21 03:14:23

问题


struct FOO{
    int a;
    int b;
    int c;
};

volatile struct FOO foo;

int main(void)
{
    foo.a = 10;
    foo.b = 10;
    foo.c = 10;
    struct FOO test = foo;

    return 0;
}

This won't compile, because struct FOO test = foo; generates an error:

error: binding reference of type 'const FOO&' to 'volatile FOO' discards qualifiers

How can I copy a volatile struct into another struct in C++ (before C++11)?

Many people suggested to just delelte volatile, but I can't do that in that case, because I want to copy the current SPI-Reg setttings inside a µC and this is declared volatile by the manufacturer headers. I want to copy those settings, because the manufactuerer also provides an Library to use the SPI for EnDat-Communication, and I don't have access to the source-code. Since I have to change the SPI-Reg-Settings during runtime I want to easyly get back to the library SPI-settings without calling the init_endat()-lib fkt again (it's unspecified what happens if i call it twice).

Could I possibly use memcopy() for that?

As suggested, this is a copy of the following question.

Why am I not provided with a default copy constructor from a volatile?


回答1:


This is ill-formed because FOO has an implicit copy constructor defined as:

FOO(FOO const&);

And you write FOO test = foo; with foo of type volatile FOO, invoking:

FOO(volatile FOO const&);

But references-to-volatile to references-to-non-volatile implicit conversion is ill-formed.

From here, two solutions emerge:

  1. don't make volatile to non-volatile conversions;
  2. define a suited copy constructor or copy the object members "manually";
  3. const_cast can remove the volatile qualifier, but this is undefined behavior to use that if your underlying object is effectively volatile.

Could I possibly use memcopy() for that?

No you cannot, memcpy is incompatible with volatile objects: thre is no overload of it which takes pointers-to-volatile, and there is nothing you can do without invoking undefined behavior.

So, as a conclusion, your best shot if you cannot add a constructor to FOO is to define:

FOO FOO_copy(FOO volatile const& other)
{
    FOO result;
    result.a = other.a;
    result.b = other.b;
    result.c = other.c;
    return result;
}

Or with C++11's std::tie:

FOO FOO_copy(FOO volatile const& other)
{
    FOO result;
    std::tie(result.a, result.b, result.c) = std::tie(other.a, other.b, other.c);
    return result;
}



回答2:


To give another approach to an answer, to address why this doesn't make sense, rather than just where the C++ standard says this is invalid:

The whole point of volatile is that you have precise control over which variable gets accessed when. That means given volatile int i, j;, i = 1; j = 2; and j = 2; i = 1; do not do the same thing. The compiler cannot freely transform one into the other. The same applies to reads: given volatile int i, j; int x, y;, x = i; y = j; and y = j; x = i; do not do the same thing. The presence of volatile means the accesses must happen in exactly the order you specified.

Now, in your example, what should struct FOO test = foo; do? You've never specified whether you want to first read foo.a, then foo.b, finally foo.c, or perhaps first read foo.c, then foo.b, finally foo.a, or perhaps some other order.

You can, if you wish, do this:

struct FOO test;
test.a = foo.a;
test.b = foo.b;
test.c = foo.c;

Here, you explicitly specify the order of the accesses to foo's fields, so you avoid the problem.




回答3:


You haven't provided enough details about your problem to give a more precise assessment, but the solution to whatever problem you're trying to solve is almost certainly not to use volatile. "Volatile" means that the value can change from under your feet: the two typical good use cases are variables changed from within UNIX signal handlers and memory-mapped registers. Volatile is not enough for variables shared among threads, notably.

The reason you are getting this error is that your compiler is trying to find a FOO(volatile FOO&) copy constructor, which is never automatically generated.



来源:https://stackoverflow.com/questions/49367852/volatile-struct-struct-not-possible-why

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!