Что такое «необнаружимые средства» и как они могут изменять объекты программы на C / C ++? - PullRequest
1 голос
/ 19 января 2020

В ISO / IEC 14882: 2003 (C ++ 03) указано в 7.1.5.1/8, раздел «Спецификаторы cv»:

[Примечание: volatile является подсказкой для реализации, чтобы избежать агрессивной оптимизации с использованием объекта , поскольку значение объекта может быть изменено средствами, которые не могут быть обнаружены реализацией. См. подробную информацию о семантике в разделе 1.9. Как правило, семантика volatile должна быть такой же в C ++, как и в C. ]


Эти «средства», которые не могут быть обнаружены реализацией, также уже были предметом Nawaz´ Q & A Почему мы используем ключевое слово volatile :

Однако иногда оптимизация (некоторых частей вашей программы) может быть нежелательной, поскольку может случиться так, что кто-то еще изменяет значение some_int из-за пределов программы , что компилятор не знает из, так как он не может видеть это; но это как ты это спроектировал. В этом случае оптимизация компилятора не дала бы желаемого результата!

Но, к сожалению, он упустил объяснение, что это за «средства», которые могут изменять объекты вне программы, и как они могут изменить объекты.


Мой вопрос:

  • Каковы примеры этих "необнаружимых средств" и как они могут изменять внутренние объекты программы извне? ?

1 Ответ

4 голосов
/ 19 января 2020

Указатель в памяти может быть виден другим частям той же или другой программы. Например, переменная, которая существует в общей памяти и может быть изменена другой программой.

Компилятор не может обнаружить это.

Другими примерами являются аппаратные области памяти.

Как правило, приложения, которым требуются переменные переменные, обычно работают с такими вещами, как асинхронное аудио, а на системном уровне - с прерываниями, API C и c. Большинству приложений они не нужны.

Воображаемый пример:

int v = 0;

// Some thread
SetUpdatesOn(&v);

 // Another thread
for(;;)
{
   int g = v;
   std::cout << g;
}

Предположим, что мнимая функция уровня ОС SetUpdatesOn периодически меняет передаваемую ей переменную. Если переменная не объявлена ​​как volatile, компилятор может оптимизировать вызов int g = v или предположить, что v всегда имеет одно и то же значение.

Если переменная объявлена ​​как volatile, компилятор продолжит читать ее в l oop.

Обратите внимание, что очень часто такие ошибки программирования трудно отлаживать, поскольку оптимизация может существовать только в сборках выпуска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...