Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

volatile struct = struct not possible, why?

Tags:

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?

like image 943
makum Avatar asked Mar 19 '18 16:03

makum


People also ask

Can a struct member be volatile?

Finally, if you apply volatile to a struct or union, the entire contents of the struct/union are volatile. If you don't want this behavior, you can apply the volatile qualifier to the individual members of the struct/union.

Can a struct be volatile in C?

That way, all of the registers in the struct will be treated, by the compiler, as volatile and yet it is possible to have other (e.g. RAM-based shadows) instances of said struct that are not volatile because they are not actually hardware registers underneath.


1 Answers

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; } 
like image 109
YSC Avatar answered Oct 18 '22 08:10

YSC