挥发功能

Gab*_*ern 16 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;
}
Run Code Online (Sandbox Code Playgroud)

当我编译时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
}
Run Code Online (Sandbox Code Playgroud)

很明显,编译器能够优化掉函数调用,foo()以便main()返回一个常量,即使foo()标记为volatile.所以我的问题是,volatile在限制编译器优化方面是否适用于函数声明.

(注意我对这个问题的兴趣主要是了解什么是好奇volatile而不是解决任何具体问题.)

(此外,我将此问题标记为C和C++,不是因为我认为它们是相同的语言,而是因为我有兴趣知道volatile这两种语言在这种情况下是否存在差异).

Dav*_*eas 23

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

typedef volatile int Type;
Type foo();
Run Code Online (Sandbox Code Playgroud)

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

struct test {
   void vfunction() volatile;
};
Run Code Online (Sandbox Code Playgroud)

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

struct test {
   void vfunction() volatile;
   void function();
};
volatile test t;
t.vfunction();      // ok
t.function();       // error
Run Code Online (Sandbox Code Playgroud)


Dre*_*ann 5

foo() 不易变.

这是一个返回a的函数volatile int.

这是合法的.但回来后很奇怪int.

另一方面,成员函数可能volatile出于同样的原因const- 两者都描述了对象this所指向的.

  • +1,特别是评论*但对于返回的`int`*来说很奇怪.事实上,编译器可以自由地从返回的对象中删除`volatile`限定符. (3认同)