Абстрактное объяснение В
C и C ++ есть понятие абстрактной машины . Когда код использует значение некоторой переменной, абстрактная машина говорит, что реализация должна получить доступ к значению этой переменной. Код формы statement_A; statement_B; statement_C;
должен быть выполнен в точно указанном порядке. Выражения, общие для этих трех операторов, должны пересчитываться каждый раз, когда они встречаются.
За абстрактные машины, учитывая последовательность операторов statement_A; statement_B; statement_C;
, реализация должна сначала выполнить statement_A
в полном объеме, а затем statement_B
, и в конце концов statement_C
. Реализация не может вспомнить, что вы присвоили age
значение 5. Каждое утверждение, которое ссылается, age
должно вместо этого получить доступ к значению этой переменной.
Не было бы необходимости в volatile
ключевом слове, если реализации строго выполняли код C или C ++ согласно спецификациям абстрактной машины. В абстрактных машинах C и C ++ нет понятия регистров, нет понятия общих подвыражений, и порядок выполнения является строгим.
Оба языка также имеют правила « как будто» . Реализация соответствует стандарту при условии, что эта реализация ведет себя так, как будто она выполнила все в соответствии со спецификацией абстрактной машины. Компилятор может предположить, что энергонезависимые переменные не изменяют значения между присваиваниями. Пока это не нарушает as-if
правило, последовательность statement_A; statement_B; statement_C;
может быть реализована путем выполнения части statement_C
, затем части statement_A
, затем всего statement_B
, затем остальной части statement_A
и, наконец, остальной части statement_C
.
Эти правила « как будто» не применяются к volatile
переменным. Что касается volatile
переменных и функций, реализация должна делать именно то, что вы сказали ей делать, и именно в том порядке, в котором вы сказали ей делать вещи.
Есть обратная сторона спецификации абстрактной машины: она медленная. Одним из положительных аспектов C и C ++ по сравнению с другими языками является то, что они довольно быстрые. Это не будет иметь место, если код был выполнен для этих абстрактных машин. Правила « как будто» позволяют C и C ++ быть такими быстрыми.
Ответ ELI5
что это значит, когда компилятор не «оптимизирует» адрес памяти?
«Оптимизация» адреса памяти - это продвинутая концепция, которая выходит за рамки возможностей пятилетнего ребенка. Податливые пятилетние дети будут делать именно то, что вы им скажете, ни больше, ни меньше. С помощью volatile
этого вы говорите, что реализация действует так, как будто это пять: не нужно думать, не нужно ничего оптимизировать. Вместо этого реализация должна делать именно то, что говорит ей код.
volatile
переменной, и в нем написано 5, и вы читаете его снова в следующем году, вы гарантированно получите 6.