目前为止,示例所示的 const 从理论上来说很简单。 但是,volatile 到底意味着什么?对于编译器,这意味着访问此类对象时不采用任何代码生成快捷方式。另一方面,ISO C 将声明具有相应特殊属性的每个 volatile 对象指定为程序员的责任。
volatile 对象的四个常见示例为:
为内存映射 I/O 端口的对象
多个并行进程之间共享的对象
异步信号处理程序修改的对象
调用 setjmp 的函数中声明的自动存储持续时间对象,其值在 setjmp 调用和相应的 longjmp 调用之间会更改
前三个示例是具有特殊行为的对象的所有实例: 在程序执行期间的任何点均可修改其值。因此,只要 flag 具有 volatile 限定类型,以下看上去的无效循环将有效。
flag = 1; while (flag);
某些异步事件将来可能将 flag 设置为零。否则,由于 flag 的值在循环主体中保持不变,编译系统会将以上循环更改为完全忽略 flag 值的真正死循环。
第四个示例涉及调用 setjmp 的函数的局部变量,因此进一步加以讨论。有关 setjmp 和 longjmp 的行为的详细信息指示,与第四种情况匹配的对象的值是不可预测的。对于最需要的行为,longjmp 必须检查调用 setjmp 的函数与调用 longjmp 的函数之间的各个堆栈帧是否有保存的寄存器值。由于存在异步创建堆栈帧的可能性,使该作业更加困难。
在将自动对象声明为 volatile 限定类型时,编译器必须生成与程序员编写的内容完全匹配的代码。因此,这类自动对象的最近值始终在内存中,而不仅在寄存器中,并且可保证在调用 longjmp 时为最新。