Точные требования к volatile
в текущем стандарте C ++ в подобном случае, насколько я понимаю, не совсем четко определены стандартом, поскольку стандарт на самом деле не касается многопоточности. Это в основном подсказка компилятора. Поэтому вместо этого я расскажу о том, что происходит в типичном компиляторе.
Сначала предположим, что компилятор компилирует ваши функции независимо, а затем связывает их вместе. В любом примере у вас есть цикл, в котором вы проверяете переменную и вызываете указатель на функцию. В контексте этой функции компилятор понятия не имеет, что будет делать функция, стоящая за указателем на функцию, и поэтому он всегда должен повторно загружать b
из памяти после вызова. Таким образом, volatile
здесь не имеет значения.
Расширяя это до вашего первого фактического случая, и позволяя компилятору выполнять оптимизацию всей программы, поскольку pf
является изменчивым, компилятор все еще не знает, на что он будет указывать (он даже не может предположить, что это либо f1
или f2
!), И, следовательно, также не может делать какие-либо предположения о том, что будет неизменным при вызове указателя функции - и поэтому volatile
на b
все еще не имеет значения.
Ваш второй случай на самом деле проще - vb
в нем красная сельдь. Если вы устраните это, вы увидите, что даже в полностью однопоточной семантике вызов функции-указателя может изменить b
. Вы ничего не делаете с неопределенным поведением, и поэтому программа должна работать правильно без volatile
- помните, что, если вы не рассматриваете ситуацию с настройками внешних потоков, volatile
- это запрет. Следовательно, без vb
на рисунке вам, возможно, не понадобится volatile
, и совершенно очевидно, что добавление vb
ничего не меняет.
Таким образом, в итоге: вам не нужно volatile
в любом случае. Разница между ними заключается в том, что в первом случае, если fp
не является энергозависимым, достаточно продвинутый компилятор может оптимизировать b
, тогда как во втором случае он не может работать даже без энергозависимости в программе во втором случае. , На практике я не ожидаю, что какие-либо компиляторы действительно выполнят эту оптимизацию.