请考虑以下代码:
0.1 + 0.2 == 0.3 -> false
Run Code Online (Sandbox Code Playgroud)
0.1 + 0.2 -> 0.30000000000000004
Run Code Online (Sandbox Code Playgroud)
为什么会出现这些不准确之处?
可能重复:
C++:什么时候有挥发性关键字帮你?
我从来没有用过它,但我想知道为什么人们会用它?它到底是做什么的?我搜索了论坛,发现它只是C#或Java主题.
在C/C++中使用volatile关键字有什么用?声明变量volatile与不声明变量之间有什么区别volatile?
我知道当从几个线程或进程写入的内存位置读取时,volatile属性应该用于该位置,就像下面的一些情况一样,但我想知道更多关于它对编译器的实际限制,基本上是什么规则编译器在处理这种情况时必须遵循,并且有任何例外情况,尽管可以同时访问存储器位置,但程序员可以忽略volatile关键字.
volatile SomeType * ptr = someAddress;
void someFunc(volatile const SomeType & input){
//function body
}
Run Code Online (Sandbox Code Playgroud) 我读到了volatile内存映射硬件寄存器,ISR和多线程程序中C 关键字的用法.
1)注册
uint8_t volatile * pReg;
while (*pReg == 0) { // do sth } // pReg point to status register
Run Code Online (Sandbox Code Playgroud)
2)ISR
int volatile flag = 0;
int main()
{
while(!flag) { // do sth }
}
interrupt void rx_isr(void)
{
//change flag
}
Run Code Online (Sandbox Code Playgroud)
3)多线程
int volatile var = 0;
int task1()
{
while (var == 0) { // do sth }
}
int task2()
{
var++;
}
Run Code Online (Sandbox Code Playgroud)
我可以看出为什么编译器可以错误地优化while以防万一1)如果volatile不存在,'因为变量是由硬件进行的,编译器可能看不到代码所做的变量的任何变化. …
我注意到libstdc ++的实现std::ignore带有一个const T&参数,它不能绑定到一个volatile的rvalue.因此,以下代码无法编译:
#include <tuple>
#include <utility>
struct C {};
using VC = C volatile;
int main() {
std::tuple<VC> t;
std::tie(std::ignore) = std::move(t);
}
Run Code Online (Sandbox Code Playgroud)
(http://coliru.stacked-crooked.com/a/7bfc499c1748e59e)
这违反了标准,还是有一个条款会导致这种未定义的行为?
假设我有以下功能.
std::mutex mutex;
int getNumber()
{
mutex.lock();
int size = someVector.size();
mutex.unlock();
return size;
}
Run Code Online (Sandbox Code Playgroud)
这是一个volatile在声明大小时使用关键字的地方吗?如果我不使用volatile,会返回值优化还是别的东西会破坏这段代码?someVector可以从程序具有的众多线程中的任何一个更改大小,并且假设只有一个线程(修饰符除外)调用getNumber().
在这种情况下,两个负载会合二为一吗?如果这是依赖于架构的,那么说英特尔的现代处理器会是什么情况?我相信原子负载相当于英特尔处理器中的正常负载。
void run1() {
auto a = atomic_var.load(std::memory_order_relaxed);
auto b = atomic_var.load(std::memory_order_relaxed);
// Some code using a and b;
}
void run2() {
if (atomic_var.load(std::memory_order_relaxed) == 2 && /*some conditions*/ ...) {
if (atomic_var.load(std::memory_order_relaxed) * somevar > 3) {
/*...*/
}
}
}
Run Code Online (Sandbox Code Playgroud)
run1()并且run2()只是使用相同原子变量的两个负载的两个场景。编译器能否将这种两种加载的场景合并为一种加载并重用它?
我可以知道volatile变量存储在内存中的哪个位置吗?
如果我声明全局意味着它存储在内存中的哪个位置?
volatile int a =10;
int main()
{
printf("Global A value=%d",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)如果我在函数内部声明意味着它在哪里存储在内存中?
int main()
{
volatile int a =10;
printf("Local A value=%d",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)它是否存储在堆栈/ RAM /数据段中?
请澄清我的疑虑.