volatile
是告诉编译器不要优化引用,这样每次读/写都不会使用寄存器中存储的值,而是进行真正的内存访问。我可以理解它对某些普通变量很有用,但不理解volatile
如何影响指针。
volatile int *p = some_addr;
int a = *p; // CPU always has to load the address, then does a memory access anyway, right?
如果它被声明为int *p = some_addr
会有什么区别?
答案 0 :(得分:125)
表格
的指针volatile int* p;
是指向int
的指针,编译器将其视为volatile
。这意味着编译器将假定p
指向的变量有可能已更改,即使源代码中没有任何内容表明可能会发生这种情况。例如,如果我将p
设置为指向常规整数,那么每次读取或写入*p
时,编译器都会意识到该值可能已意外更改。
volatile int*
还有一个用例:如果您将int
声明为volatile
,那么您不应该使用常规int*
来指出它。例如,这是个坏主意:
volatile int myVolatileInt;
int* ptr = &myVolatileInt; // Bad idea!
原因是C编译器不再记得ptr
指向的变量是volatile
,因此它可能会错误地将*p
的值缓存在寄存器中。实际上,在C ++中,上面的代码是一个错误。相反,你应该写
volatile int myVolatileInt;
volatile int* ptr = &myVolatileInt; // Much better!
现在,编译器会记住ptr
点volatile int
,因此它不会(或不应该!)尝试通过*ptr
优化访问。
最后一个细节 - 您讨论的指针是指向volatile int
的指针。你也可以这样做:
int* volatile ptr;
这表示指针本身是volatile
,这意味着编译器不应该尝试将指针缓存在内存中或尝试优化指针值,因为指针本身可能被其他东西重新分配(硬件等)如果你想得到这个野兽,你可以将它们组合在一起:
volatile int* volatile ptr;
这表示指针和指针可能会意外更改。编译器无法优化指针本身,也无法优化指向的内容。
希望这有帮助!
答案 1 :(得分:9)
此代码volatile int *p = some_addr
声明指向volatile int
的指针。指针本身不是volatile
。
如果你需要指针是volatile和int,你需要使用:
volatile int * volatile p;
我无法想到你需要使用它的情况。
答案 2 :(得分:0)
关于volatile的有用性: 如果您需要检查内存,这是必需的,则需要通过硬件(例如串行接口控制器)对其进行修改。它在嵌入式系统的世界中都有其应用,您可以在非常接近硬件的情况下工作而无需任何操作系统。