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-5.5.0/gcc/C_002b_002b-Volatiles.html