挥发功能

时间:2013-03-07 22:41:22

标签: c++ c volatile

摘要:关键字volatile在C和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和C ++,不是因为我认为它们是同一种语言,而是因为我有兴趣知道volatile在这两种情况下的作用是否存在差异语言)。

2 个答案:

答案 0 :(得分:21)

在您的代码中,volatile关键字不适用于该函数,但对于返回类型,它相当于:

typedef volatile int Type;
Type foo();

现在,在C ++中,您可以使用与volatile限定符相同的方式创建成员函数const,并且行为相同:

struct test {
   void vfunction() volatile;
};

基本上你不能在类型的volatile(const)实例上调用非易失性(alterantive non-const)函数:

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

答案 1 :(得分:5)

foo()不易变。

这是一个返回volatile int

的函数

哪个是合法的。但对于返回的int来说很奇怪。

另一方面,成员函数可以是volatile,原因可能是const - 两者都描述了this指向的对象。