Reputation: 10063
Summary: What does the keyword volatile
do when applied to a function declaration in C and in C++?
Details:
I see that it's possible to compile a function that is marked as volatile
. However, I'm not sure what compiler optimization (if any) this prevents. For instance I created the following test case:
volatile int foo() {
return 1;
}
int main() {
int total = 0;
int i = 0;
for(i = 0; i < 100; i++) {
total += foo();
}
return total;
}
When I compile with clang -emit-llvm -S -O3 test.c
(gcc would also work but the llvm IR is more readable in my opinion) I get:
target triple = "x86_64-unknown-linux-gnu"
define i32 @foo() #0 {
ret i32 1
}
define i32 @main() #0 {
ret i32 100
}
So obviously the compiler was able to optimize away the calls to function foo()
so that main()
returns a constant, even though foo()
is marked as volatile
. So my question is whether volatile
does anything at all when applied to a function declaration in terms of limiting compiler optimizations.
(Note my interest in this question is mostly curiosity to understand what volatile
does rather than to solve any specific problem.)
(Also I have marked this question as both C and C++ not because I think they are the same language, but because I am interested to know if there are differences in what volatile
does in this case in these two languages).
Upvotes: 18
Views: 28598
Reputation: 63775
foo()
is not volatile.
It's a function that returns a volatile int
.
Which is legal. But strange for a returned int
.
Member functions, on the other hand, can be volatile
for the same reason they can be const
-- both describe the object this
is pointing to.
Upvotes: 6
Reputation: 208353
In your code, the volatile
keyword does not apply to the function, but to the return type, it is the equivalent of:
typedef volatile int Type;
Type foo();
Now, in C++ you can make a member function volatile
, in the same way that the const
qualifier, and the behavior is the same:
struct test {
void vfunction() volatile;
};
Basically you cannot call a non-volatile (alterantively non-const) function on a volatile (const respectively) instance of the type:
struct test {
void vfunction() volatile;
void function();
};
volatile test t;
t.vfunction(); // ok
t.function(); // error
Upvotes: 29