何时使用C++中的const volatile,register volatile和static volatile?

33

我想了解在使用registerconststatic关键字时,volatile关键字的不同用法。我不确定这些关键字的效果是什么,因此需要您帮忙。

register volatile int T=10;

建议编译器将T存储在寄存器中,并且T的值可以从外部(操作系统、硬件、另一个线程)进行修改。
const volatile int T=10;

程序本身无法修改T,但是可以从代码外部修改T。

static volatile int T=10;

如果T是一个类的数据成员,这意味着该类的所有对象都具有相同的T值,并且可以从外部某处修改T。如果T是文件中的全局变量,则其他文件中的源代码(属于该项目的一部分)无法访问T,但可以从外部某处访问T。如果T是函数中的局部变量,则一旦它被初始化,它将一直存在于内存中,直到程序结束,并且可以从外部某处修改。
我的想法正确吗?有没有经验丰富的C++开发人员可以给出一个现实应用的例子,或者这种情况非常少见?
1个回答

38
register volatile int T=10;

volatile 限定符意味着编译器不能对 T 进行优化或重新排列访问顺序,而 register 是向编译器提示 T 将被大量使用。如果获取了 T 的地址,则编译器会简单地忽略该提示。请注意,register 被弃用但仍在使用。

实际用途:

我从未使用过它,也从未感到需要它,现在也无法想到任何用途。


const volatile int T=10;

const 限定符表示 T 不能通过代码进行修改。如果您尝试这样做,编译器将提供一条诊断信息。 volatile 在第一种情况下仍然具有相同的含义。编译器无法优化或重新排序对 T 的访问。

实际用途:

  • 以只读模式访问共享内存。
  • 以只读模式访问硬件寄存器。

static volatile int T=10;

static 存储限定符为 T 提供了静态存储期 (C++11 §3.7) 和 内部链接,而 volatile 仍然控制优化和重新排序。

实际应用:

  • volatile 相同,但需要对象具有静态存储期并且无法从其他翻译单元访问。

2
第二个问题,你确定你说的是const-volatile 对象,还是const-volatile 引用(或指向const-volatile对象的指针)?因为似乎const-volatile对象无法映射到硬件... - user541686
1
@Mehrdad:我指的是指向const-volatile对象的指针,类似于:unsigned char const volatile *hd_addr; - Alok Save
1
是的,你的例子展示了 const volatile int T=10; 这是不同的。 :) - user541686
2
@Mehrdad:啊,好的,这就是OP引用的例子。我试图将其用作解释的占位符,并稍后添加了示例,所以有点错过了它。无论如何,既然你指出了它,那些值得看到的人现在可以在评论中看到它 :) - Alok Save
1
@Mehrdad:链接器脚本可以将符号绑定到内存映射中的特定位置,因此只要const volatile int不是static,它就有可能映射到硬件。像这样的链接器技巧最好避免使用,因为它们并不是很直观,但我曾经在低级嵌入式设备中看到过它们的使用。 - cooperised
@Gary99 那个链接涉及到 volatile,它显然具有各种实际应用。你引用的上下文是关于特定组合 register volatile 的有用性的评论。 - cooperised

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接