Функции-Члены 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


это полностью аналогично тому, как const строительство.

если у вас


беспокойство, если у меня есть 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 можно назвать летучих и энергонезависимые объекты. Энергонезависимая функция-член может вызываться только для нелетучих объект.

http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr028.htm