18

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).

Gabriel Southern
  • 9,602
  • 12
  • 56
  • 95
  • 21
    You have a function returning a `volatile int`, not a volatile function. – ildjarn Mar 07 '13 at 22:42
  • 2
    I don't think this is really a *duplicate* and the close is incorrect, but whatever. An important distinction in C++ is `volatile` member functions. Check out http://stackoverflow.com/questions/4826719/c-volatile-member-functions – Nik Bougalis Mar 07 '13 at 22:46
  • Take a look on http://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766 – Mihai8 Mar 07 '13 at 23:08
  • 1
    @user1929959 : _Extremely_ outdated... – ildjarn Mar 07 '13 at 23:16
  • @ildjarn Not fallen to think that if a post is old then it is useful. Volatile function is not new. – Mihai8 Mar 07 '13 at 23:19
  • @ildjarn: That is an interesting point of view, specially considering that while written in 2001 it is more *current* now with all of the threading focus than it was when it was published. If you have any concerns other than *it's old* I invite you to treat them in this [question](http://stackoverflow.com/questions/2491495/may-volatile-be-in-user-defined-types-to-help-writing-thread-safe-code) – David Rodríguez - dribeas Mar 07 '13 at 23:20
  • 1
    @user1929959 : The point is that `volatile` is _not_ a multithreaded programmer's best friend – `std::atomic<>` is. – ildjarn Mar 07 '13 at 23:20
  • @ildjarn Don't consider c11 as be most used standard, is just experimental. – Mihai8 Mar 07 '13 at 23:23
  • 1
    @user1929959 : In that case there's [Boost.Atomic](http://www.boost.org/libs/atomic/). ;-] – ildjarn Mar 07 '13 at 23:30
  • @ildjarn See http://en.cppreference.com/w/cpp/atomic/atomic – Mihai8 Mar 07 '13 at 23:32

2 Answers2

28

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
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
6

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.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • 3
    +1, specially for the comment *But strange for a returned `int`*. As a matter of fact the compiler is free to drop the `volatile` qualifier from the returned object. – David Rodríguez - dribeas Mar 07 '13 at 23:18
  • that's the question, what's a "volatile int"??? saying it's a "volatile int" doesn't answer what a "volatile int" is. we know making an int variable volatile means no optimization. what optimization could you logically need to prevent from a function? an rvalue (temp) is already optimized. it seems completely useless. – Puddle Feb 23 '19 at 15:04
  • 1
    @Puddle nowhere in this question is the phrase "what's a volatile int". This question is asking "What does the keyword volatile do when applied to a **function**". Perhaps you have a different question to ask here? – Drew Dormann Feb 24 '19 at 16:47
  • @DrewDormann you said it yourself "Which is legal. But strange for a returned int." why's it strange? don't you understand it? when would you need to prevent optimization on a function? that's entirely why this question is being asked. anything strangely related could be relevant to answering the question. by "volatile int" you know i was referring to the example. are you saying "volatile rvalue"? if so how does that work? as if it's doing this? int x = (volatile)5; – Puddle Feb 24 '19 at 17:22