Cracking the coding interview--Q13.5

February 13, 2013
作者:Hawstein
出处:http://hawstein.com/posts/13.5.html
声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处。

题目

原文:

What is the significance of the keyword “volatile” in C?

译文:

谈谈C语言关键字”volatile”的意义(或重要性)?

解答

volatile的意思是”易变的”,因为访问寄存器比访问内存要快得多, 所以编译器一般都会做减少存取内存的优化。volatile 这个关键字会提醒编译器,它声明的变量随时可能发生变化(在外部被修改), 因此,与该变量相关的代码不要进行编译优化,以免出错。

声明一个volatile变量:

volatile int x;
int volatile x;

声明一个指针,指向volatile型的内存(即指针指向的内存中的变量随时可能变化):

volatile int *x;
int volatile *x

声明一个volatile指针,指向非volatile内存:

int* volatile x;

声明一个volatile指针,指向volatile内存(即指针和指针所指物都随机可能变化):

volatile int * volatile x;
int volatile * volatile x;

volatile在声明上的使用和const是一样的。volatile在*号左边, 修饰的是指针所指物;在*号右边修饰的是指针。

用volatile修饰的变量相关的代码不会被编译器优化,那么它有什么好处呢? 来看下面的例子:

int opt = 1;
void Fn(void){
	start:
		if (opt == 1) goto start;
		else break;
}

上述代码看起来就是一个无限循环的节奏,编译器可能会将它优化成下面的样子:

void Fn(void){
	start:
		int opt = 1;
		if (true)
			goto start;
}

由于程序中并没有对opt进行修改,因此将if中的条件设置为恒真。这样一来, 就陷入了无限循环中。但是,如果我们给opt加上volatile修饰, 表明外部程序有可能对它进行修改。那么,编译器就不会做上述优化, 上述程序在opt被外部程序修改后将跳出循环。此外, 当我们在一个多线程程序中声明了一些全局变量,且任何一个线程都可以修改这些变量时, 关键字volatile也会派上用场。在这种情况下, 我们就要明确地告诉编译器不要对这些全局变量的相关代码做优化。

继续阅读:C语言中volatile关键字的作用

全书题解目录:

Cracking the coding interview–问题与解答

全书的C++代码托管在Github上:

https://github.com/Hawstein/cracking-the-coding-interview