Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialise a volatile structure with a non-volatile structure?

Background

I'm trying to create two instances of a struct. One of them will not change and is therefore declared const, but the other may be changed asynchronously, therefore I'd like to make it volatile.

Problem

I'm trying to use the const instance of the structure to initialise the volatile one. However, if I use the volatile keyword the compiler throws this error:

passing 'volatile rect' as 'this' argument of 'rect& rect::operator=(rect&&)' discards qualifiers [-fpermissive]at line 15 col 8

Reproducible example

#include <Arduino.h>

struct rect {
    int x0;
    int y0;
    int width;
    int height;
};

const    rect outer    = {0, 0, 10, 5};
volatile rect inner;

void setup() {
    inner = {outer.x0 + 1, outer.y0 + 1,
             outer.width - 2, outer.height - 2};
}

void loop() {
    ;
}

Omitting volatile compiles fine:

rect inner = {outer.x0 + 1, outer.y0 + 1,
                            outer.width - 2, outer.height - 2};

Initialising one-by-one also works, but this is exactly what I'm trying to avoid:

inner.x0        = outer.x0 + 1;
inner.y0        = outer.y0 + 1;
inner.width     = 0;
inner.height    = outer.height - 2;

Question

What am I missing? ... It may be related to this.

like image 908
pfabri Avatar asked Oct 29 '22 14:10

pfabri


1 Answers

You are missing what the error message actually says. The compiler is telling you that to assign the whole structure in one go needs a "copy constructor" which understands the volatile qualifier and there isn't one. Have a look at this answer for a discussion of what the error means.

But when you assign the individual elements of the structure one by one no copy constructor is needed and so the code works fine. Why are you "trying to avoid" this?

What you are expecting the volatile qualifier to do? In C/C++ it ONLY prevents the compiler from optimising away your variables or the code which uses them. Nothing more.

It wouldn't be useful to define a stock copy constructor for volatile structures, since your concurrency requirements will differ from everyone else's.

To guarantee that your structure elements are assigned consistently, you may need to disable interrupts, like this:

cli();
inner.x0        = outer.x0 + 1;
inner.y0        = outer.y0 + 1;
inner.width     = 0;
inner.height    = outer.height - 2;
sei();

But you'll have to analyse precisely what you need and that's heading off topic.

like image 192
Peter Lister Avatar answered Nov 09 '22 10:11

Peter Lister