Неустойчивая функция
Резюме. Что делает ключевое слово 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
делает в этом случае на этих двух языках).
Ответы
Ответ 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
.