Функции-Члены Volatile (C++)
учитывая следующий класс:
class MyClass {
public:
int value() const {
return value_;
}
private:
volatile int value_;
};
функция-член value () также должна быть отмечена как изменчивая, чтобы избежать оптимизации, или это нормально, как написано? Спасибо.
4 ответов
функция-член value () также должна быть отмечена как изменчивая, чтобы избежать оптимизации, или это нормально, как написано?
маркировка функции-члена volatile не повлияет на то, оптимизирована она или нет. Все хорошо, как написано.
беспокойство, если у меня есть MyClass c; а затем вызовите c.value (); пару раз компилятор может подумать c.value () вернет то же значение (даже если это возможно измененный..)
похоже, что вы хотите узнать об атомарных переменных. Взгляните на std:: atomic.
Если вы действительно хотите узнать о volatile, прочитайте эту статью:http://www.cs.utah.edu / ~regehr / документы / emsoft08-препринт.pdf
беспокойство, если у меня есть MyClass c; а затем вызовите c.value (); пару раз компилятор может подумать c.value () вернет то же значение (даже если оно могло быть изменено..)
в отдельной модели компиляции, где компилятор не видит внутренних функций, он не может предположить, что они не будут иметь побочных эффектов ([ * ]) и, следовательно, не могут удалить различные вызовы функции. Если компилятор видит определение функция и вставка кода, то это видит, что член volatile
и, таким образом, не может оптимизировать его.
[*] некоторые компиляторы (а именно gcc) имеют специальные атрибуты, которые вы можете использовать, чтобы сказать ему, что функция чисто (т. е. он не имеет побочных эффектов, и выход зависит только от предоставленных аргументов), чтобы включить несколько вызовов функции, которые будут оптимизированы, например, в этом цикле:
const char* lit = "Literal";
int sum = 0;
for ( int i = 0; i < strlen(lit); ++i ) {
sum += lit[i];
}
, потому что strlen
is помеченный как чистый в библиотеке, компилятор кэширует значение и преобразует цикл в:
const char* lit = "Literal";
int sum = 0;
int __len = strlen(lit);
for ( int i = 0; i < __len; ++i ) {
sum += lit[i];
}
но библиотека должен сказать компилятор специально, что это можно сделать. Без дополнительной информации в виде атрибутов, ничего нельзя предположить и strlen
функция должна вызываться в каждой итерации цикла.
постоянные и изменчивые функции-члены (только C++)
можно вызвать функцию-член, объявленную с помощью квалификатора const постоянные и непостоянные объекты. Непостоянная функция-член может вызывается только для непостоянного объекта. Аналогично, функция-член объявлен квалификатор volatile можно назвать летучих и энергонезависимые объекты. Энергонезависимая функция-член может вызываться только для нелетучих объект.