7.1 Когда осуществляется доступ к объекту типа volatile в C++?
Стандарт C++ отличается от стандарта C в обработке объектов типа volatile. Он не определяет, что представляет собой доступ к объекту volatile, за исключением того, что C++ должен вести себя аналогично C в отношении volatile, где это возможно. Однако разные свойства выражений lvalue в C и C++ усложняют поведение. G++ ведет себя так же, как GCC при доступе к volatile. См. Volatile для описания поведения GCC.
Спецификации языков C и C++ отличаются, когда объект используется в контексте void:
volatile int *src = somevalue; *src;
Стандарт C++ определяет, что такие выражения не претерпевают преобразования lvalue в rvalue, и что тип дереференцированного объекта может быть неполным. Стандарт C++ не указывает явно, что именно преобразование lvalue в rvalue отвечает за вызов доступа. Существует основание полагать, что это так, поскольку в противном случае некоторые простые выражения станут неопределенными. Однако, чтобы не удивить большинство программистов, G++ обрабатывает дереференцирование указателя на объект типа volatile с полным типом так же, как GCC обрабатывает эквивалентный тип в C. Если объект имеет неполный тип, G++ выдает предупреждение; если вы хотите принудительно получить ошибку, вы должны принудительно преобразовать в rvalue, например, с помощью static_cast.
При использовании ссылки на volatile G++ не обрабатывает эквивалентные выражения как доступ к volatile, а вместо этого выдает предупреждение о том, что к volatile нет доступа. Основание для этого в том, что в противном случае становится трудно определить, где происходит доступ к volatile, и невозможно игнорировать значение, возвращаемое функциями, возвращающими ссылки на volatile. Опять же, если вы хотите принудительно считать, преобразуйте ссылку в rvalue.
G++ реализует такое же поведение, как GCC, при присваивании объекту volatile — повторного считывания присвоенного объекта нет, присвоенное rvalue используется повторно. Обратите внимание, что в выражениях присваивания C++ используются lvalue, и если они используются как lvalue, то к объекту volatile обращаются. Например, vref ссылается на vobj, как ожидалось, в приведенном ниже примере:
volatile int vobj; volatile int &vref = vobj = something;
Далее: Ограниченные указатели, Наверх: Расширения C++ [Содержание][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/C_002b_002b-Volatiles.html