Мне было интересно, если в следующем сценарии временный изменчивый квалификатор даст правильное поведение. Предположим, что ISR собирает значения в массиве, и как только достаточно значений было собрано, это сигнализирует о готовности.
int array[10]; // observe no volatile here
int idx = 0; // neither here
volatile bool ready = false; // but here
Вот ISR это псевдокод
ISR() {
if (idx < 10)
array[idx++] = ...;
ready = (idx >= 10);
}
Предположим, мы можем гарантия тот array
будет только для чтения после ready
сигнализируется, и элементы доступны через определенный метод только:
int read(int idx) {
// temporary volatile semantics
volatile int *e = (volatile int*)(array + idx);
return *e;
}
что, кажется, разрешено в соответствии с CPP-справочник
Преобразование энергонезависимого значения в энергозависимый тип не оказывает влияния. Чтобы получить доступ к энергонезависимому объекту с использованием изменчивой семантики, его адрес должен быть приведен к указателю на volatile, а затем доступ должен быть сделан через этот указатель.
Для полноты основной рутины делает следующее
void loop() {
if (ready) {
int val = read(0); // Read value
// do something with val.
}
}
В таком случае я должен ожидать, чтобы прочитать правильные значения из array
или является изменчивым для элементов массива, необходимых для гарантии того, что запись в массив изнутри ISR()
на самом деле выполняется в оперативной памяти?
Обратите внимание, что Почему летучий нужен в C? не детализирует, нужен ли в этом особом случае volatile.
записывать в array[]
не через volatile
так что вы не можете полагаться на это наблюдаемое поведение. Да, компилятор должен выполнить некэшированное чтение array
, но это только половина картины.
Ты говоришь о порядок как будто это зависит от volatile
— это не так.
Других решений пока нет …