Подтвердить что ты не робот

Неустойчивая функция

Резюме. Что делает ключевое слово volatile при применении к объявлению функции в C и на С++?

Подробнее

Я вижу, что можно скомпилировать функцию, помеченную как volatile. Однако я не уверен, что оптимизация компилятора (если таковая имеется) предотвращает это. Например, я создал следующий тестовый пример:

volatile int foo() {
  return 1;
}

int main() {
  int total = 0;
  int i = 0;
  for(i = 0; i < 100; i++) {
    total += foo();
  }

  return total;
}

Когда я компилирую с помощью clang -emit-llvm -S -O3 test.c (gcc также работает, но llvm IR более читабельна, на мой взгляд), я получаю:

target triple = "x86_64-unknown-linux-gnu"

define i32 @foo() #0 {
  ret i32 1
}

define i32 @main() #0 {
  ret i32 100
}

Таким образом, очевидно, что компилятор смог оптимизировать вызовы функции foo(), чтобы main() возвращал константу, даже если foo() отмечен как volatile. Поэтому мой вопрос заключается в том, что volatile делает что-либо вообще при применении к объявлению функции в терминах ограничения оптимизации компилятора.

(Обратите внимание, что мой интерес к этому вопросу в основном заключается в любопытстве, чтобы понять, что volatile, а не для решения какой-либо конкретной проблемы.)

(Также я отметил этот вопрос как C и С++ не потому, что я думаю, что они являются одним и тем же языком, а потому, что мне интересно узнать, существуют ли различия в том, что volatile делает в этом случае на этих двух языках).

4b9b3361

Ответ 1

В вашем коде ключевое слово volatile не относится к функции, но к типу возвращаемого значения это эквивалент:

typedef volatile int Type;
Type foo();

Теперь на С++ вы можете создать функцию-член volatile, так же, как и для const, и поведение будет одинаковым:

struct test {
   void vfunction() volatile;
};

В принципе вы не можете вызвать функцию энергонезависимой (альтернативно неконстантной) в volatile (const соответственно) экземпляре типа:

struct test {
   void vfunction() volatile;
   void function();
};
volatile test t;
t.vfunction();      // ok
t.function();       // error

Ответ 2

foo() нестабилен.

Это функция, которая возвращает volatile int.

Это законно. Но странно для возвращенного int.

Функции-члены, с другой стороны, могут быть volatile по той же причине, что они могут быть const.