17

摘要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这两种语言在这种情况下的作用是否存在差异)。

4

2 回答 2

27

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

typedef volatile int Type;
Type foo();

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

struct test {
   void vfunction() volatile;
};

基本上,您不能在该类型的易失性(分别为 const)实例上调用非易失性(或者非 const)函数:

struct test {
   void vfunction() volatile;
   void function();
};
volatile test t;
t.vfunction();      // ok
t.function();       // error
于 2013-03-07T23:08:15.110 回答
5

foo()不挥发。

它是一个返回volatile int.

这是合法的。但奇怪的一回int

另一方面,成员函数可能volatile出于相同的原因const——它们都描述了对象this所指向的对象。

于 2013-03-07T23:08:14.813 回答